10

Mã sau có bị ảnh hưởng tiêu cực do thiếu kế thừa ảo không?Thừa kế ảo có cần thiết khi các lớp cơ sở không chứa thành viên dữ liệu không?

Nếu vậy, sẽ tác động tiêu cực giống như (hoặc tệ như) những tác động tiêu cực của đa kế thừa mà không thừa kế ảo nếu class Ađã chứa dữ liệu thành viên?

class A 
{ 
public : 
    virtual ~A () { } 
    virtual int foo () const = 0 ; 
} ; 

class B : public A 
{ 
public : 
    virtual ~B () { } 
} ; 

class C : public A 
{ 
public : 
    virtual ~C () { } 
} ; 

class D : public B , public C 
{ 
public : 
    virtual int foo () const { return 12 ; } 
} ; 
+1

Có vẻ [như bạn làm cần 'virtual' thấy ở đây] (http://coliru.stacked-crooked.com/view?id=8bd2970b897e9b44), đó là nếu bạn mong đợi một con trỏ đến A bắt nguồn từ B để có cùng giá trị như thể nó được bắt nguồn từ C. – Niall

+1

Bằng cách, bạn cần khai báo một destructor ảo với một thực hiện trống trong A. Xem http://stackoverflow.com/questions/461203/when-to-use-virtual-destructors – Notinlist

+0

@Notinlist Cảm ơn bạn đã nắm bắt. Tôi đã thêm các destructor ảo vào A, B và C để đảm bảo an toàn. – Giffyguy

Trả lời

4

Giả sử rằng bạn muốn sử dụng A như một giao diện chung, nếu bạn không thực hiện các thừa kế ảo mà bạn sẽ không thể làm điều gì đó như thế này, bởi vì có hai con đường thừa kế đến lớp cơ sở A từ con D:

int main() 
{ 
    D d; 
    const A& a = d; 

    std::cout << a.foo() << " " << d.foo() << " " << std::endl; 
} 

Nếu bạn không cần phải sử dụng một D như một A sau đó (A) tại sao bạn có nó như là một cơ sở trừu tượng ở nơi đầu tiên và (B) không , không cần thừa kế là ảo.

1
class B : public virtual A { } ; 
class C : public virtual A { } ; 

Sử dụng thừa kế ảo trên các lớp trung gian, lớp D của bạn sẽ chỉ có một trường hợp duy nhất của lớp A, và mã của bạn sẽ biên dịch tốt

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