多继承的构造函数顺序
#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 B2
construct B1
construct B3
construct B1
construct B2
construct 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 B1
construct B2
construct B1
construct B2
construct A
destruct A
destruct B2
destruct B1
destruct B2
destruct 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,而不会调用 B
class 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;
}