菱形继承
两个子类继承同一个父类,而又有子类又分别继承这两个子类,就称作菱形继承
多重继承产生的二义性
假设有一个基类,他派生了两个子类分别继承于它,比如说下面这个例子:
class A {
public:
A(int d) {
cout << "A()" << endl;
_data = d;
}
protected:
int _data;
};
class X:public A
{
public:
X(int x = 0):A{x}{}
void setdata(int d) {
_data = d;
}
};
class Y:public A
{
public:
Y(int x = 0):A{x}{}
int getdata() {
return _data;
}
};
基类中有一份公共数据_data,两个子类分别对它进行了继承,如果我们调用类X中的setdata修改数据,再调用class Y中的getdata(),得到的数据是不一致的,原因是重名数据存在于各自的作用域中,产生了二义性
为了解决这个问题(产生数据冗余),我们可以使用菱形继承:我们对上述代码按下面步骤进行修改
1 提取各父类中 相同的成员 构成祖父类
2 让各父类继承祖父类
3 虚继承:是一种继承的扩展:virtual
虚继承实现了在多继承中只保留一份共同成员,防止产生数据冗余
class A {
public:
A(int d) {
cout << "A()" << endl;
_data = d;
}
protected:
int _data;
};
class X:virtual public A
{
public:
X(int x = 0):A{x}{}
void setdata(int d) {
_data = d;
}
};
class Y:virtual public A
{
public:
Y(int x = 0):A{x}{}
int getdata() {
return _data;
}
};
class Z:public X,public Y
{
public:
Z(int x) :A{ x } {}
void dis() {
cout << _data << endl;
}
};
这样就实现了了菱形继承
菱形继承的构造:菱形继承的构造由孙子类来完成对祖先类的构造,两个子类中使用默认参数构造即可(注:子类还是要对父类完成构造,只不过参数改为默认参数即可,传参由孙子类来完成)
实例:
class furniture {
public:
furniture(string color,int weight):_color{color},_weight{weight}{}
void descripte() {
cout << _color << endl;
cout << _weight << endl;
}
protected:
string _color;
int _weight;
};
class sofa:virtual public furniture{
public:
sofa(string color = "black", int weight = 100):furniture(color, weight){}
void sit() {
cout << "take a sit..." << endl;
}
};
class Bed:virtual public furniture{
public:
Bed(string color = "black",int weight = 100):furniture(color,weight){}
void sleep() {
cout << "have a sleep..." << endl;
}
};
class SofaBed :public sofa, public Bed {
public:
SofaBed(string color, int weight) :furniture(color, weight) {}
};
int main() {
sofa s1("blue", 123);
s1.sit();
s1.descripte();
Bed s2("yellow", 456);
s2.sleep();
s2.descripte();
SofaBed s3("green", 3241);
s3.sleep();
s3.sit();
s3.descripte();
system("PAUSE");
}
还没有评论,来说两句吧...