多继承的构造函数顺序
#include<bits/stdc++.h>using namespace std;/*** 多继承构造函数* */class B1 {public:B1(int i) {cout<<"construct B1"<<endl;}};class B2 {public :B2(int j) {cout<<"construct B2"<<endl;}};class B3 {public:B3() {cout<<"construct B3"<<endl;}};class C: public B2, public B1, public B3 { // 基类构造函数按照这个顺序public:C(int a, int b, int c, int d): B1(a), b2(d), b1(c), B2(b) { // 注意这个顺序无关}private: // 子对象构造函数顺序B1 b1;B2 b2;B3 b3;};int main() {C obj(1, 2, 3, 4);return 0;}
输出
construct B2construct B1construct B3construct B1construct B2construct B3
多继承的析构函数顺序
#include<bits/stdc++.h>using namespace std;/*** 多继承析构函数的顺序* */class B1 {public :B1(int x) {cout<<"construct B1"<<endl;}~B1() {cout<<"destruct B1"<<endl;}};class B2 {public:B2() {cout<<"construct B2"<<endl;}~B2() {cout<<"destruct B2"<<endl;}};class A: public B1, public B2 {public:A(int a, int b): B1(a), B2(), b1(b), b2() {cout<<"construct A"<<endl;}~A() {cout<<"destruct A"<<endl;}private:B1 b1;B2 b2;};int main() {A a(10, 20);return 0;}
输出
construct B1construct B2construct B1construct B2construct Adestruct Adestruct B2destruct B1destruct B2destruct B1
多继承时不同基类同名成员的二义性
#include<bits/stdc++.h>using namespace std;/*** 多继承中不同基类成员的二义性* */class A {public:void set_a(int a) {this->a = a;}int get(){return this->a;}private:int a;};class B {public:void set_b(int b) {this->b = b;}int get() {return this->b;}private:int b;};class C: public A, public B {public:void set_c(int c) {this->c = c;}private:int c;};int main() {C c;// c.get(); // 错误,引起了二义性,不清楚调用哪个类的get()函数// 方法一,通过作用域分辨c.A::get();c.B::get();return 0;}
#include<bits/stdc++.h>using namespace std;/*** 多继承中不同基类成员的二义性* */class A {public:void set_a(int a) {this->a = a;}int get(){return this->a;}private:int a;};class B {public:void set_b(int b) {this->b = b;}int get() {return this->b;}private:int b;};class C: public A, public B {public:void set_c(int c) {this->c = c;}int get() {cout<<c<<endl;return this->c;}private:int c;};int main() {C c;// c.get(); // 错误,引起了二义性,不清楚调用哪个类的get()函数// 方法一,通过作用域分辨// c.A::get();// c.B::get();// 方法二,覆写重名函数c.set_c(1);c.get();return 0;}
访问共同基类成员的二义性
#include<bits/stdc++.h>using namespace std;/*** 访问共同基类成员的二义性* */class A {public:void dis(){}};class B1: public A {public:void disB1() {}};class B2: public A {public:void disB2() {}};class C: public B1, public B2 {public:void disC() {}};int main() {C c;// c.dis(); // 错误,C 中包含C1和C2中的dis()函数,因此产生二义性//c.A::dis() 依然会出现二义性,因为实质上 c 包含了二份// 下面这两个是可以的,没有二义性c.B1::dis();c.B2::dis();return 0;}
虚基类概念:
#include<bits/stdc++.h>using namespace std;/*** 虚基类概念* */class A {public:void dis() {cout<<"A: a="<<a<<endl;}int a;};class B1: virtual public A {};class B2: virtual public A {};class C: public B1, public B2 {};int main() {C c;c.a = 9;c.dis();return 0;}
虚基类的初始化
#include<bits/stdc++.h>using namespace std;/*** 虚基类的初始化* */class A {public:A(int i) {a = i;cout<<"construct A"<<endl;}void dis() {cout<<"A: a="<<a<<endl;}int a;};class B1: virtual public A {public:B1(int j): A(j) {cout<<"construct B1"<<endl;}int b1;};class B2: virtual public A {public:B2(int j): A(j) {cout<<"construct B2"<<endl;}int b2;};class C: public B1, public B2 {public:C(int j): A(j), B1(j), B2(j) { // 虽然 B1和B2中都有 A 的构造函数,但是C 是A的最远派生类,只会通过最远派生类的构造函数对虚基类初始化cout<<"construct C"<<endl;}int c;};int main() {C c(3);c.a = 9;c.dis();return 0;}
虚基类构造函数的执行顺序
#include<bits/stdc++.h>using namespace std;/*** 虚基类的构造函数执行顺序* */class A{int a;public:A(){printf("construct A\n");}};class B {public:B() {printf("construct B\n");}};class B1: virtual public B, virtual public A {public:B1(int i) {printf("construct b1\n");}};class B2: public A, virtual public B {public:B2(int j) {printf("construct b2\n");}};// 虚基类并非基类派生,那么先调用虚基类的基类构造函数,再调用虚基类的构造函数// 也就是先调用 B1 和 B2 的构造函数,其中 B1 调用 B 再调用 A,而B2已经调用过B了,因此只调用A的(虚基类的构造函数已经被调用过了,那么不会再调用)// 由于 B2 不是虚继承 A,因此会再调用A,而不会调用 Bclass D: public B1, public B2 {public:D(int m, int n):B1(m), B2(n) {printf("construct D\n");}A a;};int main() {D d(1, 2);return 0;}
虚基类由最终派生类初始化
#include<bits/stdc++.h>using namespace std;/*** 虚基类由最终派生类初始化* */class A {int a;public:A(int x) {a = x;printf("virtual base a\n");}};class B: virtual public A {public:B(int i): A(i) {printf("virtual base b\n");}};class C: virtual public A {int x;public:C(int i):A(i) {printf("construct C\n");x = i;}};class ABC: public C, public B {public:ABC(int i, int j, int k): C(i), B(j), A(i) { // 由于 A 是虚基类,所以必须在这里进行初始化printf("construct ABC\n");}};int main() {ABC abc(1, 2, 3);return 0;}
