2011-12-12 24 views
32

Có thể thừa kế không có phương pháp ảo không? Trình biên dịch nói rằng mã sau đây không phải là đa hình.Không thể downcast vì lớp học không đa hình?

Ví dụ:

Class A(){ 
    int a; 
    int getA(){return a;}; 
} 


Class B(): A(){ 
    int b; 
    int getB(){return b;}; 
} 

Trong một lớp học, chúng tôi đang cố gắng để downCast từ một đối tượng A đến một đối tượng B:

A *a; 
B *b = dynamic_cast<B*>(a) 

nhưng điều này mang đến cho các lỗi sau:

cannot dynamic_cast ... (source type is polymorphic) 
+1

'a' không phải là con trỏ. Đây có phải là mã trong mã của bạn không? – littleadv

+0

Xin lỗi, một thực tế là một con trỏ. – wbarksdale

+0

Và là thời gian biên dịch lỗi hay thời gian chạy? Nếu thời gian chạy, sau đó IMHO hành vi mong đợi của nó. – littleadv

Trả lời

56

Lỗi cú pháp không chịu được, bạn không thể dynamic_cast loại không đa hình. static_cast là diễn viên bạn sẽ sử dụng trong trường hợp này, nếu bạn biết rằng đó là thực tế, một đối tượng của loại mục tiêu.

Lý do tại sao: static_cast về cơ bản có trình biên dịch thực hiện kiểm tra tại thời gian biên dịch "Có thể nhập vào đầu ra không?" Điều này có thể được sử dụng cho các trường hợp bạn đang đúc lên hoặc xuống một hệ thống phân cấp thừa kế của con trỏ (hoặc tham chiếu). Nhưng kiểm tra chỉ là lúc biên dịch, và trình biên dịch giả định bạn biết bạn đang làm gì.

dynamic_cast chỉ có thể được sử dụng trong trường hợp con trỏ hoặc dàn diễn viên tham chiếu và ngoài kiểm tra thời gian biên dịch, thời gian chạy bổ sung sẽ kiểm tra xem dàn diễn viên có hợp pháp hay không. Nó yêu cầu lớp trong câu hỏi có ít nhất 1 phương thức ảo, cho phép trình biên dịch (nếu nó hỗ trợ RTTI) thực hiện kiểm tra bổ sung này. Tuy nhiên, nếu loại được đề cập không có bất kỳ phương thức ảo nào, thì nó không thể được sử dụng.

Trường hợp đơn giản nhất, và có thể đáng giá nếu bạn đang truyền con trỏ xung quanh như thế này, là xem xét làm cho trình phá hủy lớp cơ sở ảo. Ngoài việc cho phép bạn sử dụng phép đúc động, nó cũng cho phép các trình phá hủy thích hợp được gọi khi một con trỏ lớp cơ sở bị xóa.

+0

Cảm ơn nhiều vì kiến ​​thức. Điều đó đã thành công. – wbarksdale

2
A a; 
B *b = dynamic_cast<B*>(a) 

Đây là đối tượng và b là con trỏ.

Thực ra, upcasting và downcasting đều được phép trong C++. Nhưng khi sử dụng downcasting, 2 điều cần chú ý: 1 Lớp cha cần có ít nhất một phương thức ảo. 2 Vì superclass là "nhỏ hơn" subclass, nên sử dụng đối tượng bộ nhớ một cách cẩn thận.

4

có, dynamic_cast cho các loại không đa hình không được phép. Lớp cơ sở phải có ít nhất một phương thức ảo. Chỉ khi đó lớp đó mới có thể được gọi là đa hình.

Bài viết này giải thích một ví dụ tương tự: http://www.cplusplus.com/doc/tutorial/typecasting/

+0

Dave đã đưa ra một câu trả lời hay. Tôi không có quyền nhận xét về bài đăng của anh ấy. Vì vậy, tôi đang bình luận ở đây. –

18

Bạn cần ít nhất một phương thức ảo trong một lớp học cho run-time type information (RTTI) để áp dụng thành công điều hành dynamic_cast.

11

chỉ cần tạo một destructor ảo (luôn làm cho bất kỳ lớp nào chỉ vì sự an toàn).

+7

không dành cho bất kỳ lớp nào nhưng đối với lớp học được dự định là lớp cơ sở – ParokshaX