2010-02-09 24 views
6

Giả sử tôi có một tình huống thừa kế kim cương như sau:Tại sao lớp sau có bảng ảo?

class A{ 
    public: virtual void foo(){}; 
}; 
class B: public virtual A{ 
    public: virtual void foo(){}; 
}; 
class C: public virtual A{ 
    public: virtual void foo(){}; 
}; 
class D: B, C{}; 

Dòng cuối cùng mang lại một lỗi biên dịch với lý do mơ hồ. Như tôi đã hiểu, vấn đề là trình biên dịch không biết foo nào đặt trong vtbl của D, nhưng tại sao lại có một vtbl cho D nếu nó không định nghĩa bất kỳ chức năng ảo nào của nó?

+0

Có phải "ảo" làm trình chỉ định mức bảo vệ thậm chí hợp lệ trên các dòng khai báo lớp của bạn (ví dụ: lớp B: virtual A) không? – Joe

+4

Nó không có bộ định danh bảo vệ. Nó biểu thị một lớp cơ sở ảo, đó là loại hack hợp pháp để giải quyết vấn đề kim cương. –

+0

Ah, phải, cảm ơn bạn. – Joe

Trả lời

7

Bạn đang kế thừa các lớp có chứa các chức năng ảo. Do đó, lớp của bạn có các chức năng ảo. Nó đơn giản như vậy.

+0

Sau đó, có lẽ tôi đang thiếu một cái gì đó, bởi vì khi tôi loại bỏ từ "ảo" từ đặc tả thừa kế (lớp B: A, lớp C: A), nó biên dịch và chạy. Không phải là vấn đề presist vì tôi là "kế thừa các lớp học có chứa các chức năng ảo"? – EpsilonVector

+0

Xin lỗi là lớp B: công khai A, v.v ... – EpsilonVector

+0

Xóa từ khóa 'virtual' khỏi khai báo phương thức trong' lớp B' và 'lớp C'. Biên dịch lại và xem điều gì xảy ra. –

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