class A
{
public:
A(int a) :m_a(a) {}
int getMa() { return m_a; }
private:
int m_a;
};
class B :public A
{
public:
B(int a, int b) :A(a), m_b(b) {}
private:
int m_b;
};
class C :public A
{
public:
C(int a, int c) :A(a), m_c(c) {}
private:
int m_c;
};
class D :public B, public C
{
public:
D(int a, int b, int c, int d) :B(a, b), C(a, c), m_d(d) {}
void func()
{
/*錯誤,通路不明确
std::cout << getMa();*/
//正确,通過B通路getMa()
std::cout << B::getMa();
}
private:
int m_d;
};
class ZooAnimal {}; //虛基類
class Bear :public virtual ZooAnimal {}; //虛繼承
class Raccoon :public virtual ZooAnimal {}; //虛繼承
//Panda隻儲存一份ZooAnimal的定義
class Panda :public Bear, public Raccoon, public Endangered {};
三、虛繼承中的類型轉換
虛繼承中也可以将派生類抓換為基類,用基類的指針/引用指向于派生類
菱形繼承中的類型轉換
菱形繼承中會發生錯誤,不能将派生類轉換為基類
原理是差不多的,就是因為派生類中擁有多份基類的實體,是以不能轉換,會産生二義性
class A {};
class B: publi A {};
class C: publi A {};
class D: public B, public C {};
int main()
{
D d;
A* pa = &d; //錯誤
return 0;
}
虛繼承中的類型轉換
class ZooAnimal {};
class Bear :public virtual ZooAnimal {};
class Raccoon :public virtual ZooAnimal {};
class Panda :public Bear, public Raccoon, public Endangered {};
void dance(const Bear&);
void rummage(const Raccoon&);
ostream& operator<<(ostream&, const ZooAnimal&);
int main()
{
Panda ying_yang;
dance(ying_yang); //正确,把一個Panda對象當成Bear傳遞
rummage(ying_yang);//正确,把一個Panda對象當成Raccoon 傳遞
cout << ying_yang; //正确,把一個Panda對象當成ZooAnimal傳遞
return 0;
}
//普通繼承
class A {
public:
A(int a);
};
class B :public A {
public:
B(int a):A(10) {}
};
class C :public B {
public:
C() :B(10) {} //可以不為A進行構造,因為A的構造已經交給B了
};
//虛繼承
class A {
public:
A(int a);
};
class B :virtual public A {
public:
B(int a):A(10) {}
};
class C :virtual public A {
public:
C(int a) :A(10) {}
};
class D :public B,public C {
public:
//D() :B(10), C(20) {} 錯誤的,必須顯式為A進行構造
D() :A(5), B(10), C(20) {} //正确
};
構造函數的執行順序
規則:虛基類總是先于非虛基類構造,與它們在繼承體系中的次序和位置無關
例如,在上面的示範案例中,構造順序為:A-->B-->C-->D
下面再示範一個有多個虛基類的例子,其構造函數執行熟悉怒為:
ZooAnimal
ToyAnimal
Character
BookCharacter
Bear
TeddyBear
class Character {};
class BookCharacter :public Character {};
class ZooAnimal {};
class Bear :public virtual ZooAnimal {};
class ToyAnimal {};
class ReddyBear :public BookCharacter, public Bear, public virtual ToyAnimal {};