菱形繼承

在探索菱形繼承遇到的問題及其總結
先說什麼是菱形繼承如圖(這只是一種)
這裏寫圖片描述

#include<iostream>
using namespace std;
class A
{

public:
    int _a;
};
class B: public A
{

public:
    int _b;
};
class C: public A
{
public:
    int _c;
};
class D:public C,public B
{
public:
    int _d;
};

int main()
{
    D d;
    d._a=1;
    d._b=2;
    d._c=3;
    d._d=4;
    return 0;
}

以以上代碼爲例進行探索
在vs2008中,在運行中出現了
這裏寫圖片描述
如圖的錯誤。這是因爲菱形繼承具有二義性和冗雜性(如下圖片可形象的進行了模擬)
這裏寫圖片描述
D對象中有兩個A成員。
如何解覺這個問題呢?
虛繼承–解決菱形繼承的二義性和數據冗餘的問題
1. 虛繼承解決了在菱形繼承體系裏面子類對象包含多份父類對象的數據冗餘&浪費空間的問題。
2. 虛繼承體系看起來好複雜,在實際應用我們通常不會定義如此複雜的繼承體系。一般不到萬不得已都不要定義菱形結構的虛繼承體
繫結構,因爲使用虛繼承解決數據冗餘問題也帶來了性能上的損耗。
我們可以對上面的代碼進行如下變化

“`

include

using namespace std;
class A
{

public:
int _a;
};
class B: virtual public A
{

public:
int _b;
};
class C: virtual public A
{
public:
int _c;
};
class D:public C,public B
{
public:
int _d;
};

int main()
{
D d;
d._a=1;
d._b=2;
d._c=3;
d._d=4;
return 0;
}
加virtual 以前的d的大小 20
這裏寫圖片描述
加virtual 以後的大小24
這裏寫圖片描述
打開監視窗口可看到如下
這裏寫圖片描述
而解決這些問題在VS下使用的是偏移量,我們調用內存窗口可發現
這裏寫圖片描述
class C的地址加20就是class A的地址,同理class B的地址加12就是class B的地址。sizeof(d)=24,所以在一定程度上會有性能損耗。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章