2013-06-09 34 views
6

tôi stumbled khi mã ví dụ này:đa kế thừa ảo

#include <iostream> 
using namespace std; 

class A { 
    int x; 
public: 
     A() { x = 1; cout << "A"; } 
}; 
class B : virtual public A { 
     int y; 
public: 
     B() { y = 2; cout << "B"; } 
}; 
class C : virtual public B, virtual public A { 
     int z; 
public: 
     C() { z = 3; cout <<"C"; } 
}; 
class D : public A, public B, public C { 
     int t; 
public: 
     D() { t = 4; cout << "D"; } 
}; 
int main() 
{ 
     D d; 
     return 0; 
} 

This code prints ABABCD và tôi không có ý tưởng tại sao. Tôi nghĩ rằng nó sẽ in A cho D : public A, sau đó AB cho D : public B, sau đó ABC cho D : public C và sau đó D, nhưng có vẻ như A chỉ được in hai lần. Cái này hoạt động ra sao?

+0

điều gì sẽ xảy ra nếu bạn thay đổi 'công khai A, công khai B , public C' to 'virtual public A, public B, public C'? – cmh

+0

@cmh 'ABBCD' ... –

+0

Có lẽ đó là hướng dẫn .. – cmh

Trả lời

8

Thứ tự xây dựng cơ sở là (bỏ qua cơ sở ảo) từ trái sang phải khi chúng được nhập vào mối quan hệ kế thừa. Khi bạn thêm căn cứ ảo, những căn cứ này được khởi tạo trước tiên (trước bất kỳ cơ sở không phải ảo nào) theo cách từ trái sang phải theo chiều sâu.

Bây giờ điều này sẽ giải thích đầu ra.

D: A, B, C

A không có căn cứ ảo, B có một ảo Một cơ sở, vì vậy đó là người đầu tiên khởi: "A". Sau đó C có một cơ sở B ảo, vì vậy đó là cơ sở tiếp theo được khởi tạo. Tại thời điểm này, một subobject ảo đã được khởi tạo, do đó chỉ có B constructor được đánh giá là "AB". Tại thời điểm này tất cả các cơ sở ảo đã được xây dựng và các cơ sở phi ảo được xây dựng, đầu tiên A, sau đó B, sau đó C, sau đó là kiểu D hoàn chỉnh, sinh ra "ABABCD". Các đối tượng phụ ảo đã được xây dựng xong, vì vậy chúng không được xây dựng lại.

Một số điều cần lưu ý. Một cơ sở ảo chỉ được chia sẻ với các subobject khác sẵn sàng chia sẻ nó (tức là có nó như một cơ sở ảo). Không có giới hạn về số lần một cơ sở ảo có thể được chia sẻ trong một đối tượng hoàn chỉnh (tức là cơ sở ảo A được chia sẻ nhiều lần, kể cả từ các đối tượng B khác nhau)

+0

Cảm ơn rất nhiều, điều này giải thích nó! Thông tin chi tiết tuyệt vời –