C++多重繼續與虛繼續剖析。本站提示廣大學習愛好者:(C++多重繼續與虛繼續剖析)文章只能為提供參考,不一定能成為您想要的結果。以下是C++多重繼續與虛繼續剖析正文
本文以實例情勢較為周全的講述了C++的多重繼續與虛繼續,是年夜家深刻進修C++面向對象法式設計所必需要控制的常識點,詳細內容以下:
1、多重繼續
我們曉得,在單繼續中,派生類的對象中包括了基類部門 和 派生類自界說部門。異樣的,在多重繼續(multiple inheritance)關系中,派生類的對象包括了每一個基類的子對象和自界說成員的子對象。上面是一個多重繼續關系圖:
class A{ /* */ }; class B{ /* */ }; class C : public A { /* */ }; class D : public B, public C { /* */ };
C繼續了A,派生類D又繼續了B和C,如圖所示,一個D對象中含有一個B部門、一個C部門(個中又含有一個A部門)和在D中聲明的非靜態數據成員:
結構與析構:
結構一個派生類對象將起首結構它的一切基類子對象,個中基類的結構次序與派生列表中基類的湧現次序堅持分歧,即B –> A –> C –> D。
燒毀一個派生類對象的次序正好與其創立的次序相反,即析構函數的挪用次序正好與結構函數相反,即D –> C –> A –> B。留意派生類的析構函數只擔任消除派生類自己分派的資本(析構函數體),派生類的成員及基類都是主動燒毀的(隱式析構階段)。
類型轉換:
在多重繼續的情形下,可以令某個可拜訪基類的指針或援用直接指向一個派生類對象。編譯器不會在派生類向基類的幾種轉換中停止比擬和選擇,在它看來轉換就任意一種基類都一樣好。
2、虛繼續
雖然在派生列表中不許可統一個基類湧現兩次,但現實上派生類可以屢次繼續統一個類。
派生類平日會含有繼續鏈上每一個類對應的子部門。在下面的兩種情形中,class D都直接地繼續了class A兩次,那末意味著class D中包括了class A的兩份拷貝。所以在一個class D的對象中將含有2組class A的成員,此時若不加前綴限制符直接應用某個成員將激發“二義性”毛病:
class A{ public: A():str("name"){}; string str; void print(){cout << str << endl;}; }; class B : public A { }; class C : public A { }; class D : public B, public C { }; int main(){ D d; d.str = "songlee"; // 毛病:對成員‘str'的要求有歧義 d.print(); // 毛病:對成員‘print'的要求有歧義 return 0; }
固然你可使用感化域 d.B::str="songlee"; 和 d.B::print(); 來躲避“二義性”毛病,但這並沒有從基本上處理成績。
為懂得決上述成績,C++供給了虛繼續(virtual inheritance)的機制。虛繼續的目標是令某個類作作聲明,許諾情願同享它的基類。個中,同享的基類子對象稱為虛基類。在這類機制下,豈論虛基類在繼續系統中湧現若干次,在派生類中都只包括獨一一個同享的虛基類子對象。我們指定虛基類的方法是在派生列表中添加症結字virtual:
class A{ public: A():str("name"){}; string str; void print(){cout << str << endl;}; }; class B : virtual public A { }; // 虛繼續,A為虛基類 class C : virtual public A { }; // 症結字public和virtual的次序隨便 class D : public B, public C { }; int main(){ D d; d.str = "songlee"; // 准確 d.print(); // 准確 return 0; }
經由過程在派生列表中添加virtual(症結字public和virtual的次序隨便)指定A為虛基類,B和C將同享A的統一份實例,如許在D的對象中也將只要A的獨一一份實例,所以A的成員可以被直接拜訪,而且不會發生二義性。
虛繼續最典范的運用是iostream繼續於istream和ostream,而istream和ostream虛繼續於ios:
class istream : virtual public ios { /* */ }; class ostream : virtual public ios { /* */ }; class iostream : public istream, public ostream { /* */ };
另外還須要留意:
1.支撐向基類的慣例類型轉換。也就是說即便基類是虛基類,也能經由過程基類的指針或援用操作派生類的對象。
2.虛繼續只是處理了一個派生類對象中存在統一個基類的多份拷貝的成績,並沒有處理多個基類存在同名成員的二義性成績。
3.在虛繼續中,虛基類是由最低層的派生類擔任初始化的。如上例中,當創立一個D對象時,D位於派生的最低層並由它擔任初始化同享的A基類部門。
4.含有虛基類的對象的結構次序與普通的多重繼續的結構次序稍有差別:先初始化虛基類子對象(最低層派生類擔任),然後按派生列表中的次序順次對直接基類(非虛)停止初始化。
5.析構的次序與結構的次序正好相反。