cat bear
\ /
panda
在这个继承结构中,类 Animal
是基类,类 cat
和 bear
都直接继承自 Animal
,而类 panda
继承自 cat
和 bear
。当使用传统的继承方式时,panda
类将会继承两份 Animal
类的实例,这会导致冗余。
以下代码就是典型的菱形继承的例子:
class Animal
{
public:
Animal();
~Animal();
int m_nAge;
};
class Cat : public Animal
{
public:
Cat();
~Cat();
};
class bear:public Animal
{
public:
bear();
~bear();
};
class Panda:public Cat,public bear
{
public:
Panda();
~Panda();
};
Animal
类:Animal
类是一个基类,具有一个 m_nAge
成员变量,用于表示动物的年龄。
Cat
类和 bear
类:Cat
类和 bear
类分别是 Animal
类的公有派生类。它们继承了 Animal
类的成员变量和方法。
Panda
类:Panda
类同时公有派生自 Cat
类和 bear
类,从而继承了这两个类的成员。由于 Cat
类和 bear
类都是从 Animal
类继承而来的,因此 Panda
类实际上包含了两份 Animal
类的成员变量 m_nAge
,这导致冗余数据。
在构造函数中设置标志,创建panda对象后得到的结果:创建一个Panda对象,Animal构造了两次。
此时我在主程序中进行panda对象的创建,并尝试对panda继承下来的的m_nAge
对象进行赋值:
此时程序报错,并提示Panda
的m_nAge
成员不明确,原因其实就是因为Panda
继承自Cat
和bear
两个类,那么就意味着Panda
类继承了两份 Animal
类的成员变量 m_nAge
,此时使用panda->m_nAge = 10;
对Panda
的变量进行赋值编译器就会混淆;如果不想程序爆红就在赋值时就必须成员变量的继承来源:
int main() {
Panda * panda = new Panda;
//成员变量的赋值
panda->Cat::m_nAge = 10;
panda->bear::m_nAge = 15;
std::cout << "Panda Age:" << panda->Cat::m_nAge << " Panda AgeB:" << panda->bear::m_nAge << std::endl;
delete panda;
system("pause");
return 0;
}
panda->Cat::m_nAge = 10;
:给 panda
对象中 Cat
类的成员变量 m_nAge
赋值为 10
。
panda->bear::m_nAge = 15;
:给 panda
对象中 bear
类的成员变量 m_nAge
赋值为 15
。
就算解决了程序不报错的问题其实菱形继承(多继承)时还会出现其他问题:
1.数据冗余:每个派生类实例都会包含基类实例的副本,这可能会导致内存空间的浪费,特别是在多重继承的情况下,可能会存在多份相同的基类数据。 2.数据一致性:如果多个派生类实例共享同一个基类实例,那么当修改其中一个派生类实例中的基类数据时,会影响到其他共享同一基类实例的派生类实例,这可能会导致数据不一致的问题。 3.维护困难:当多个派生类实例共享同一个基类实例时,可能会增加代码的复杂性和维护成本,因为需要确保在任何修改基类数据的地方都能正确地处理多个派生类实例。 4.生命周期问题:如果派生类实例在不同的时间点创建和销毁,而共享的基类实例在某个派生类实例被销毁后还继续存在,这可能会导致悬挂指针或内存泄漏等问题
这个时候就可以使用虚继承对以上问题进行统一解决;
虚继承
虚继承通过使用关键字 virtual
来解决这个问题。当一个类以虚继承方式继承自一个基类时,无论该类被多次继承,其基类的实例只会在继承层次结构中的最顶层被创建一次。这意味着,对于上面的菱形继承问题,使用虚继承后,D
类将只继承一份 A
类的实例。
回到上述例子:
class Animal
{
public:
Animal();
~Animal();
int m_nAge;
}
//使用虚继承
class Cat : public virtual Animal
{
public:
Cat();
~Cat();
};
//使用虚继承
class bear:public virtual Animal
{
public:
bear();
~bear();
## 最后
**自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。**
**深知大多数网络安全工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**
**因此收集整理了一份《2024年网络安全全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。**
![img](https://img-blog.csdnimg.cn/img_convert/e8956841a72a998322e7aca7b3fd313f.png)
![img](https://img-blog.csdnimg.cn/img_convert/5a1bf2f6c46e0468e17181d91eac76d1.png)
![img](https://img-blog.csdnimg.cn/img_convert/0864e897187a46b5fa28ef8f04b282fa.png)
![img](https://img-blog.csdnimg.cn/img_convert/ac86c20ed5a6baaaa2270d2ba2a7c227.png)
![img](https://img-blog.csdnimg.cn/img_convert/17d76b0d99ee3d91a8ed186423567b95.png)
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上网络安全知识点!真正的体系化!**
[**如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!**](https://bbs.csdn.net/topics/618653875)
**由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!**
点!真正的体系化!**
[**如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!**](https://bbs.csdn.net/topics/618653875)
**由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!**