日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++虚继承时的构造函数

發(fā)布時間:2025/4/5 c/c++ 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++虚继承时的构造函数 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

在虛繼承中,虛基類是由最終的派生類初始化的,換句話說,最終派生類的構(gòu)造函數(shù)必須要調(diào)用虛基類的構(gòu)造函數(shù)。對最終的派生類來說,虛基類是間接基類,而不是直接基類。這跟普通繼承不同,在普通繼承中,派生類構(gòu)造函數(shù)中只能調(diào)用直接基類的構(gòu)造函數(shù),不能調(diào)用間接基類的。

下面我們以菱形繼承為例來演示構(gòu)造函數(shù)的調(diào)用:

#include <iostream> using namespace std;class A{public:A(int a);protected:int m_a; };A::A(int a):m_a(a) {}class B:virtual public A{public:B(int a,int b);public:void display();protected:int m_b;};B::B(int a, int b):A(a),m_b (b) {}void B::display() {cout<<"m_a="<<m_a<<", m_b="<<m_b<<endl; }class C:virtual public A{public:C(int a,int c);public:void display();protected:int m_c;};C::C(int a,int c):A(a),m_c(c){}void C::display() {cout<<"m_a="<<m_a<<" ,m_c="<<m_c<<endl; }//間接派生類D;class D:public B,public C{public:D(int a,int b,int c,int d);public:void display();private:int m_d;};D::D(int a, int b, int c, int d) :A(a),B(a,b),C(a,c),m_d(d){}void D::display(){cout<<"m_a="<<m_a<<", m_b="<<m_b<<", m_c="<<m_c<<", m_d="<<m_d<<endl; }int main(){B b(10,20);b.display();C c(30,40);c.display();D d(50,60,70,80);d.display();return 0;}

運(yùn)行結(jié)果:
m_a=10, m_b=20
m_a=30, m_c=40
m_a=50, m_b=60, m_c=70, m_d=80

請注意第 50 行代碼,在最終派生類 D 的構(gòu)造函數(shù)中,除了調(diào)用 B 和 C 的構(gòu)造函數(shù),還調(diào)用了 A 的構(gòu)造函數(shù),這說明 D 不但要負(fù)責(zé)初始化直接基類 B 和 C,還要負(fù)責(zé)初始化間接基類 A。而在以往的普通繼承中,派生類的構(gòu)造函數(shù)只負(fù)責(zé)初始化它的直接基類,再由直接基類的構(gòu)造函數(shù)初始化間接基類,用戶嘗試調(diào)用間接基類的構(gòu)造函數(shù)將導(dǎo)致錯誤。

現(xiàn)在采用了虛繼承,虛基類 A 在最終派生類 D 中只保留了一份成員變量 m_a,如果由 B 和 C 初始化 m_a,那么 B 和 C 在調(diào)用 A 的構(gòu)造函數(shù)時很有可能給出不同的實參,這個時候編譯器就會犯迷糊,不知道使用哪個實參初始化 m_a。

為了避免出現(xiàn)這種矛盾的情況,C++ 干脆規(guī)定必須由最終的派生類 D 來初始化虛基類 A,直接派生類 B 和 C 對 A 的構(gòu)造函數(shù)的調(diào)用是無效的。在第 50 行代碼中,調(diào)用 B 的構(gòu)造函數(shù)時試圖將 m_a 初始化為 90,調(diào)用 C 的構(gòu)造函數(shù)時試圖將 m_a 初始化為 100,但是輸出結(jié)果有力地證明了這些都是無效的,m_a 最終被初始化為 50,這正是在 D 中直接調(diào)用 A 的構(gòu)造函數(shù)的結(jié)果。

另外需要關(guān)注的是構(gòu)造函數(shù)的執(zhí)行順序。虛繼承時構(gòu)造函數(shù)的執(zhí)行順序與普通繼承時不同:在最終派生類的構(gòu)造函數(shù)調(diào)用列表中,不管各個構(gòu)造函數(shù)出現(xiàn)的順序如何,編譯器總是先調(diào)用虛基類的構(gòu)造函數(shù),再按照出現(xiàn)的順序調(diào)用其他的構(gòu)造函數(shù);而對于普通繼承,就是按照構(gòu)造函數(shù)出現(xiàn)的順序依次調(diào)用的。

修改本例中第 50 行代碼,改變構(gòu)造函數(shù)出現(xiàn)的順序:

D::D(int a, int b, int c, int d): B(90, b), C(100, c), A(a), m_d(d){ }

雖然我們將 A() 放在了最后,但是編譯器仍然會先調(diào)用 A(),然后再調(diào)用 B()、C(),因為 A() 是虛基類的構(gòu)造函數(shù),比其他構(gòu)造函數(shù)優(yōu)先級高。如果沒有使用虛繼承的話,那么編譯器將按照出現(xiàn)的順序依次調(diào)用 B()、C()、A()。

《新程序員》:云原生和全面數(shù)字化實踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

總結(jié)

以上是生活随笔為你收集整理的C++虚继承时的构造函数的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。