2011-10-04 40 views
8

Điều tôi nghĩ là loại động đó có nghĩa là đối tượng được phân bổ động bằng cách sử dụng new. Trong trường hợp sau, bạn có nói p trỏ đến loại động hoặc loại đối tượng tĩnh không? Trong tiêu chuẩn, nó không nói về loại động là đối tượng năng động.Loại động của đối tượng

1.3.3 - Loại đối tượng có nguồn gốc nhiều nhất (1.8) mà từ đó ký hiệu được biểu thị bằng biểu thức giá trị. [Ví dụ: nếu con trỏ (8.3.1) p có loại tĩnh là "con trỏ đến lớp B" trỏ đến đối tượng thuộc lớp D, bắt nguồn từ B (khoản 10), loại động của biểu thức * p là "D." Tài liệu tham khảo (8.3.2) được xử lý tương tự. ]

Ngoài ra những gì nó báo giá sau có nghĩa

Loại động của một biểu thức rvalue là loại tĩnh của nó

class Base { 
    virtual void foo(){} 
}; 

class Derived : public Base { 
    void foo(){} 
}; 

int main() 
{ 
    Derived d; 
    Base *p = &d; 
} 

Trả lời

19

Điều tôi nghĩ là loại động có nghĩa là đối tượng được phân bổ động bằng cách sử dụng mới.

Không.

Loại động là loại thực của đối tượng có thể được truy cập thông qua tham chiếu (bao gồm con trỏ) trỏ đến loại cơ sở thuộc loại thực của nó.

Nghĩa là, nếu chúng ta có:

class A { 

}; 

class B : public A { }; 


B l; 
A& k = l; 

đây k là một tham chiếu đến một đối tượng kiểu A, nhưng loại thực sự của đối tượng được gọi, loại năng động của nó, là B.

Ở đây "động" có nghĩa là "chỉ được biết đến trong thời gian chạy".

+0

+1 Rõ ràng, súc tích, ví dụ hay. – Lou

+3

+1, nhưng tôi nghĩ bạn có thể làm ví dụ rõ ràng hơn bằng cách thêm ví dụ không sử dụng mới. –

+0

Sẽ không 'A & k = B();' đủ? – arne

5

Các tĩnh loại là loại biến, là loại duy nhất được biết tại thời gian biên dịch (do đó được coi là tĩnh - không thể thay đổi). loại động là loại đối tượng đang thực sự được chỉ ở thời gian chạy. Năng động ở đây có nghĩa là nó chỉ được biết trong thời gian chạy, có nghĩa là nó có thể thay đổi (cụ thể là một biến có thể trỏ vào các đối tượng khác nhau của các loại khác nhau).

Việc sử dụng new trong nội dung này không liên quan, như ví dụ của bạn cho thấy. Trong chính của bạn, loại tĩnh và động của dDerived, bởi vì nó không phải là một con trỏ hoặc tham chiếu. Tuy nhiên, p có loại tĩnh là Base, nhưng trong mã của bạn, loại động sẽ là Derived.

3

Trong ngôn ngữ được nhập tĩnh, chẳng hạn như C++ hoặc Java chẳng hạn, static có thể tham khảo thông tin được biết tại thời gian biên dịch trong khi dynamic đề cập đến thông tin được biết khi chạy.

Ví dụ:

struct Base { virtual std::string name() const { return "Base"; } }; 

struct Derived: Base { std::string name() const { return "Derived"; } }; 

void print(Base const& b) { std::cout << b.name() << "\n"; } 

Trong phương pháp print, loại static của bBase const&. Do đó, trình biên dịch sẽ kiểm tra tất cả các phương thức được gọi là tồn tại trong ngữ cảnh của đối tượng Base.

Tuy nhiên, khi thực hiện đến, cuộc gọi đến name, như phương pháp này là ảo, được thực hiện liên quan đến các loại dynamic của đối tượng với:

  • này có thể Base
  • này có thể Derived
  • này có thể là một lớp được thừa kế từ Base mà chúng ta biết chưa

Vì vậy, trong ví dụ sau:

int main(int argc, char* argv[]) { 
    if (argc == 1) { 
    Base base; 
    print(); 
    } else { 
    Derived derived; 
    print(derived); 
    } 
}; 
  • Các staticdynamic loại baseBasederivedDerived.
  • Trong phương pháp print, loại static của bBase (luôn luôn)
  • Tùy thuộc vào số lượng các đối số, dynamic của b là một trong hai Base hoặc Derived

Đó là một sai lầm hiện tại để giả định tính đa hình đó nhất thiết phải dựa trên phân bổ bộ nhớ động, nhưng hai khái niệm, trong khi không trực giao, có thể được sử dụng mà không có nhau trong một số điều kiện.

-1

Phân bổ bộ nhớ động luôn được thực hiện tại thời gian chạy.nó có thể đạt được bằng từ khóa "mới". nhưng có thêm một trường hợp như được đề cập trong bài toán của bạn * p = & d ở đây vì bạn đã tạo hàm lớp cơ sở "Ảo", nó cho trình biên dịch xử lý "p" theo nội dung chứ không phải theo loại con trỏ mà nó thuộc về .so đây là một trong những phân bổ bộ nhớ động như trình biên dịch không bao giờ biết địa chỉ của đối tượng lớp bạn sẽ lưu trữ trong thời gian chạy, nó chỉ biết loại con trỏ nào (tức là lớp con trỏ cơ sở hoặc con trỏ lớp dẫn xuất).

Các vấn đề liên quan