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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++关于虚基类、构造函数、析构函数、成员对象的两个程序浅析

發(fā)布時間:2023/11/30 c/c++ 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++关于虚基类、构造函数、析构函数、成员对象的两个程序浅析 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

預備博客:

C++虛繼承中構(gòu)造函數(shù)和析構(gòu)函數(shù)順序問題以及原理
C++派生類含有成員對象構(gòu)造函數(shù)析構(gòu)函數(shù)順序
C++虛基類成員可見性

程序一如下:

#include<iostream> using namespace std; class A { public:A(int a) :x(a) { cout << "A constructor..." << x << endl; }int f() { return ++x; }~A() { cout << "destructor A..." << endl; } private:int x; }; class B :public virtual A { private:int y;A Aobj; public:B(int a, int b, int c) :A(a), y(c), Aobj(c) { cout << "B constructor..." << y << endl; }int f() {A::f();Aobj.f();return ++y;}void display() { cout << A::f() << "\t" << Aobj.f() << "\t" << f() << endl; }~B() { cout << "destructor B..." << endl; } }; class C :public B { public:C(int a, int b, int c) :B(a, b, c), A(0) { cout << "C constructor..." << endl; } }; class D :public C, public virtual A { public:D(int a, int b, int c) :C(a, b, c), A(c) { cout << "D constructor..." << endl; }~D() { cout << "destructor D...." << endl; } }; int main() {D d(7, 8, 9);d.f();d.display();return 0; }

同時還要注意調(diào)用函數(shù)的時候順序為從右往左

解析:首先我們調(diào)用D的構(gòu)造函數(shù),發(fā)現(xiàn)D虛繼承了A,直接繼承了C,間接繼承了B,B中含有成員對象Aobj,因此構(gòu)造函數(shù)的調(diào)用順序為:
A(9)【首先調(diào)用虛基類的構(gòu)造函數(shù),輸出A constructor...9】
A(9)【接下來調(diào)用B的構(gòu)造函數(shù),因為B含有成員對象Aobj,所以先調(diào)用Aobj的構(gòu)造函數(shù),輸出A constructor...9】
B(7,8,9)【運行B的構(gòu)造函數(shù),輸出B constructor...9】
C(7,8,9)【運行C的構(gòu)造函數(shù),輸出C constructor...】
D(7,8,9)【運行D的構(gòu)造函數(shù),輸出D constructor...】
d.f()【因為d中沒有f方法,因此我們在其基類中找,發(fā)現(xiàn)其間接基類B和虛基類A中含有方法f,但是B中的方法優(yōu)先級更高,因此訪問的是B中的方法,B中的方法f會調(diào)用A中的方法f,A::x=10,然后調(diào)用Aobj.f(),則Aobj.x=10,然后y=10】
d.dispaly()【運行B的方法,因為輸出的時候是從右往左輸出的,所以先調(diào)用B中的方法f,此時A::x=11,Aobj.x=11,y=11,同時函數(shù)返回11,然后再調(diào)用Aobj.f(),返回12,再調(diào)用A::f(),返回12,輸出12 12 11】
~D()【開始析構(gòu),調(diào)用順序和調(diào)用構(gòu)造函數(shù)的順序相反,先是D,然后再調(diào)用C的,調(diào)用B的,調(diào)用Aobj的,調(diào)用A的,輸出destructor D....】
~C()【沒有輸出】
~B()【輸出destructor B...】
~A()【輸出destructor A...】
~A()【輸出destructor A...】

運行結(jié)果:

程序二如下:

#include <iostream> using namespace std; class Base1 { public:Base1(){cout << "class Base1!" << endl;} }; class Base2 { public:Base2(){cout << "class Base2!" << endl;} }; class Level1 :public Base2, virtual public Base1 { public:Level1(){cout << "class Level1!" << endl;} }; class Level2 : public Base2, virtual public Base1 { public:Level2(){cout << "class Level2!" << endl;} }; class TopLevel :public Level1, virtual public Level2 { public:TopLevel(){cout << "class TopLevel!" << endl;} }; int main() {TopLevel obj;return 0; }

解析:理解這個程序需要對含有虛基類的構(gòu)造順序有比較深刻的認識。
類TopLevel直接繼承了Level1,虛繼承了類Level2,然后這兩個類又直接繼承了類Base2,虛繼承了類Base1,因此最后類TopLevel虛繼承了類Base1和類Level2。

由虛基類首先進行構(gòu)造可知,我們首先運行的是類Base1的構(gòu)造函數(shù)
【輸出class Base1!】
然后運行類Level2的構(gòu)造函數(shù),發(fā)現(xiàn)虛基類Base1已經(jīng)構(gòu)造,則構(gòu)造直接繼承的類Base2
【輸出class Base2!】
【輸出class Level2!】
再依次運行非虛基類,即類Level1的構(gòu)造函數(shù)
【輸出class Base2!】
【輸出class Level1!】
最后運行TopLevel的構(gòu)造函數(shù)
【輸出class TopLevel!】

運行結(jié)果:

總結(jié)

以上是生活随笔為你收集整理的C++关于虚基类、构造函数、析构函数、成员对象的两个程序浅析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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