多重继承
更新一些自己在学习中遇到的问题
多重继承的重名访问
#include <iostream>
using namespace std;
class A
{
public:
int a;
void show(){cout << "A " << a << endl;}
};
class B:public A
{
public:
int a;
void show(){cout << "B " << a << endl;}
};
class C : public A
{
public:
int a;
void show(){cout << "C " << a << endl;}
};
class D : public C, public B
{
public:
int a;
void show(){cout << "D " << a << endl;}
};
-
这段代码中,若主函数直接写
void main()
{
D d;
d.a = 5;
d.show();
}
则a 和*show()*函数都会调用派生类D中的,而不会调用ABC中的
-
但是这个时候,如果想访问B或者C中的a和*show()*该这样做:
void main()
{
D d2;
d2.B::a = 5;
d2.B::show();
}
-
我们知道此时的D类中是有两份基类A中的成分,此时调用A中的a的话,会出现什么问题呢:
void main()
{
D d2;
d2.A::a = 5;
d2.A::show();
}
而这段代码也奇迹般的执行出来了:
但是在编译区会有:
可见,这样做并不是很好的行为
虚基类
#include <iostream>
using namespace std;
class A
{
public:
A(int a):a(a){ cout << "调用A构造" << endl; }
protected:
int a;
};
class B : public A
{
public:
B(int a): A(a){ cout << "调用B构造" << endl; }
};
class C :public A
{
public:
C(int a) :A(a){ cout << "调用C构造" << endl; }
};
class D :public B, public C
{
public:
D(int a, int b) :B(a), C(b){ cout << "调用D构造" << endl; }
};
void main()
{
D d(2, 5);
}
-
按照输出的情况来看,会有两个基类 A的数据成员a,相当于在D的对象中会有两段内存,名字都是a,实际上这样的情况是一般不需要的
-
采用虚基类的方式来做,可以避免这种情况:
#include <iostream>
using namespace std;
class A
{
public:
A(int a):a(a){ cout << "调用A构造 " <<a<< endl; }
protected:
int a;
};
class B : virtual public A
{
public:
B(int a): A(a){ cout << "调用B构造 " <<a<< endl; }
};
class C :virtual public A
{
public:
C(int a) :A(a){ cout << "调用C构造 " <<a<< endl; }
};
class D :public B, public C
{
public:
D(int a, int b,int c) :B(a), C(b),A(c){ cout << "调用D构造 " << c<< endl; }
};
void main()
{
D d(2, 5,8);
}
注意这句初始化语句:
D(int a, int b,int c) :B(a), C(b),A(c){ cout << "调用D构造 " << c<< endl; }
-
可以看出,调用顺序为:A(c)->B(a)->C(b),而且在调用B,C的构造函数时,直接跨过了语句A(a)
-
更改一下继承顺序:
class D :public C, public B
按照继承的顺序调用构造函数,和书写构造函数的顺序D(int a, int b,int c) :B(a), C(b),A(c){ cout << "调用D构造 " << c<< endl; } 无关
-
内存中D的对象又有几个数据a 呢?