最喜欢的还是放肆的敲打键盘
✨写在前面
书接上文, C++继承的知识在这一篇博客就完结了。而这最后一篇博客就是讲一个多继承的语法以及用到多继承的一个菱形继承案例,一起学习吧~
✨✨ 感兴趣的同学可以订阅一下我的这个《C++入门》专栏喔~✨✨
✨目录
多继承
和Java不同的是:C++允许一个类直接继承多个类。
语法 :class 子类:继承方式 父类1,继承方式 父类2,继承方式 父类...
特点
1、由于多继承是被C++允许的,所以多继承的对象模型和前面所讲一致:会将所有父类的属性都继承下来并占用内存空间
2、继承的时候有可能会出现同名成员,需要加作用域来区分。
示例:
class A
{
public:
A()
{
m_A = 100;
}
int m_A;
};
class B
{
public:
B()
{
m_A = 200;
}
int m_A;
};
//子类需要继承base1和base2
class Son :public A, public B
{
public:
Son()
{
m_C = 300;
m_D = 400;
}
int m_C;
int m_D;
};
void test01()
{
Son son;
cout << sizeof(son) << endl;
cout << "第一个父类的m_A:" << son.A::m_A << endl;
cout << "第二个父类的m_A:" << son.B::m_A << endl;
}
int main()
{
test01();
system("pause");
return 0;
}
A、B两个类作为Son类的基类,同时都有m_A属性。A类无参构造默认m_A的值为100, B类无参构造默认m_A的值为200,然后Son类里面声明m_C和m_D属性,并在无参构造的赋值。在test01方法中创建子类对象son,可以用sizeof计算一下该对象所占内存空间,结果为16。这是因为整型占四个字节,两个基类加上自身一共四个整型,所以占用16个字节的空间。
由于A和B类属性名相同,所以我们在利用子类访问时需要加作用域,看下具体运行结果:
C++实际开发中不建议使用多继承,可以看到遇到同名的还需要加作用域,会带来不必要的麻烦,但是这个形式需要了解到。
菱形继承
概念
两个派生类继承同一个基类,又有某个类同时继承这两个派生类,这种继承称为菱形继承,或者钻石继承。
图示:
问题的出现
1、B继承了A的数据,C同样继承了A的数据,当D使用数据时,就会产生二义性。
2、D继承A的数据继承了两份,然而我们只需要一份,所以会造成空间的浪费
利用虚继承可以解决菱形继承问题——virtual
示例:
class A
{
public:
int m_Age;
};
class B :virtual public A{};
class C:virtual public A{};
class D :public B, public C{};
void test02()
{
D d;
d.B::m_Age = 18;
d.C::m_Age = 28;
//当菱形继承,当两个父类拥有相同的数据,需要加作用域来区分
cout << d.B::m_Age << endl;
cout << d.C::m_Age << endl;
cout << d.m_Age << endl;
}
void main()
{
test02();
}
利用虚继承可以解决菱形继承问题。在继承之前加上关键字virtual变为虚继承A类称为虚基类,B类和C类都继承A类,然后D类同时继承B类和C类,那么必会导致继承的属性变成双份,会造成毫无意义的资源浪费。而加上virtual之后,m_Age为共有属性,仅此一份,无论在B和C中怎样改,都会是最后修改的那个结果。既然是一份数据,也可以不加作用域,直接访问m_Age属性。
运行截图:
✨总结
终于把继承学完了,最后这个案例也是比较经典。那么下一次就该是多态内容的学习了。让我们共同学习,一起进步吧。