2009-01-07 56 views
43

Ý nghĩa của thừa kế "ảo" là gì?thừa kế ảo

tôi thấy đoạn mã sau, và không hiểu ý nghĩa của các từ khóa virtual trong bối cảnh sau đây:

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

Have a [đọc những điều này] (http://stackoverflow.com/questions/21558/in-c-virtual-base-class#21607) (nó được yêu cầu trước). –

Trả lời

38

ảo thừa kế được sử dụng để giải quyết vấn đề DDD (Dreadful kim cương trên thức chiết khấu).

Nhìn vào ví dụ sau, nơi bạn có hai lớp kế thừa từ lớp cơ sở tương tự:

class Base 
{ 

public: 

virtual void Ambig(); 

}; 

class C : public Base 
{ 

public: 

//... 

}; 

class D : public Base 
{ 
public: 

    //... 

}; 

Bây giờ, bạn muốn tạo ra một lớp mới kế thừa cả từ các lớp C và D (cả hai đều đã thừa kế hàm Base :: Ambig()):

class Wrong : public C, public D 
{ 

public: 

... 

}; 

Trong khi bạn xác định các lớp "sai" ở trên, bạn thực sự đã tạo ra DDD (Diamond thức chiết khấu vấn đề), bởi vì bạn không thể gọi:

Wrong wrong; 
wrong.Ambig(); 

Đây là một chức năng không rõ ràng bởi vì nó được định nghĩa hai lần:

Wrong::C::Base::Ambig() 

Và:

Wrong::D::Base::Ambig() 

để ngăn chặn loại vấn đề, bạn nên sử dụng thừa kế ảo, mà sẽ biết để tham khảo các ri ght Ambig() chức năng.

Vì vậy, - xác định:

class C : public virtual Base 

class D : public virtual Base 

class Right : public C, public D 
+10

'Sai' có thể rất chính xác là' Chính xác'. Nó phụ thuộc vào tình hình. MI bình thường và MI ảo đều có vị trí của chúng, ngay cả trong các mô hình kim cương (không đáng sợ) phát sinh. Chỉ cần nhớ rằng không có kích thước phù hợp với tất cả. –

+3

Tôi nghĩ bạn đang thu hút sự chú ý đến điều sai - với các lớp "Sai" và "Đúng" của bạn. Chúng giống nhau vì một lý do - chúng không phải là vấn đề. Mặc dù bạn đã có được thừa kế ảo cho cha mẹ C và D, nhưng về cơ bản bạn đã vượt qua nó - C và D là những thứ "sai" và cần được sửa, không phải lớp học xuất phát từ cả hai. – Kevin