|
【【空上雪如煙】C++虛擬繼承,分析的很透徹】http://toutiao.com/group/6520788240876700163/?iid=15906422033&app=explore_article×tamp=1518269540&tt_from=copy_link&utm_source=copy_link&utm_medium=toutiao_ios&utm_campaign=client_share 假設(shè)我們有類 A 、類 B 和類 Test ,類 Test 具有類 A 和類 B 的全部屬性,并且它們都具有 temp 屬性,現(xiàn)在我們需要在類 Test 中實(shí)現(xiàn)對(duì) temp 屬性的設(shè)定與讀取,故寫出以下程序: #include <iostream>class Base{public: int temp;
};class A : public Base{
};class B : public Base{
};class Test : public A, public B{public: void setValue(int val){
temp = val;
} void print(){ std::cout << temp << std::endl;
}
};int main(){
Test T = Test();
T.setValue(1004);
T.print(); return 0;
} 費(fèi)了好大力氣寫出來的程序,保存后編譯居然掛了 0.0 這是因?yàn)槎嘀乩^承使基類拷貝了多次,最后子類調(diào)用相同屬性的話就會(huì)產(chǎn)生二義性的問題。 對(duì)于上面的程序我們可以這樣更改使之編譯通過: class Test : public A, public B{public: void setValue(int val){
A::temp = val;
} void print(){ std::cout << B::temp << std::endl;
}
}; 程序輸出為0。 這樣就解決了二義性的問題,但這樣的代碼顯得臃腫,而且相同的屬性被拷貝了多次還會(huì)浪費(fèi)內(nèi)存。 虛擬繼承就可以輕松解決上面出現(xiàn)的問題,子類依舊繼承基類,但此時(shí)不是內(nèi)存的拷貝,而是指向基類的指針,占用一份指針的內(nèi)存。 虛擬繼承程序如下: #include <iostream>class Base{public: int temp;
};class A : virtual public Base{
};class B : virtual public Base{
};class Test : public A, public B{public: void setValue(int val){
temp = val;
} void print(){ std::cout << temp << std::endl;
}
};int main(){
Test T = Test();
T.setValue(1004);
T.print(); return 0;
} 應(yīng)用虛繼承的方式,既解決了二義性的問題,也解決了資源浪費(fèi)的問題,美滋滋~ 溫馨提示: 虛擬繼承雖好,但是不能貪杯,在開發(fā)過程中我們應(yīng)該避免使用多重繼承,它會(huì)使得程序變得更加復(fù)雜,故出錯(cuò)的可能性就更高。 補(bǔ)充虛繼承內(nèi)存占用大小(32位機(jī),from百科): #include <iostream> using namespace std;
/* 大小為4 */class A
{
public:
int a;
};
/* 大小為12,變量a,b共8字節(jié),虛基類表指針4 */class B :virtual public A
{
public:
int b;
};
/* 與B一樣12 */class C :virtual public A
{
public:
int c;
};
/* 24,變量a,b,c,d共16,B的虛基類指針4,C的虛基類指針4 */class D :public B, public C
{
public:
int d;
};
int main() {
A a;
B b;
C c;
D d;
cout << sizeof(a) << endl;
cout << sizeof(b) << endl;
cout << sizeof(c) << endl;
cout << sizeof(d) << endl;
return 0;
} 關(guān)注小編 私信 C語言資料 獲取學(xué)習(xí)資料 |
|
|