商城网站模板dede,wordpress小程序生成,开发板组装实验报告,网站设计 做鼠标效果菱形继承概念#xff1a;
两个派生类继承同一个基类
又有某个类同时继承两个派生类
这种继承又被称为菱形继承#xff0c;或者钻石继承
定义一个基类Animal#xff0c;两个派生类Sheep、Camal#xff0c;SheepCame继承于两个派生类 class Animal
{
public:int m_Age;
}…菱形继承概念
两个派生类继承同一个基类
又有某个类同时继承两个派生类
这种继承又被称为菱形继承或者钻石继承
定义一个基类Animal两个派生类Sheep、CamalSheepCame继承于两个派生类 class Animal
{
public:int m_Age;
};
class Sheep : public Animal { };
class Camel : public Animal { };
class SheepCamel : public Sheep, public Camel { }; void test() { SheepCamel S; S.m_Age 20;//报错SheepCamel::m_Age不明确 } 问题1
当创建SheepCamel类对象直接初始化m_Age时会出现二义性即不知是继承于Sheep父类还是Camel父类
若想初始化m_Age则需要加作用域来强调继承于哪个父类 void test() { SheepCamel S; S.Sheep::m_Age 10; S.Camel::m_Age 20; cout S.Sheep::m_Age endl; // 10 cout S.Camel::m_Age endl;// 20 } 问题2
菱形继承中SheepCamel子类会继承两份数据即羊驼获得了10和20两个年龄这造成了资源浪费因为我们只需要一份数据即羊驼是不应该有两个年龄的
解决方法
利用虚继承即可解决问题。即将共同基类设置为虚基类 虚基类的定义class 派生类名 : virtual 继承方式 基类名 class Animal
{
public:int m_Age;
};
class Sheep : virtual public Animal { };
class Camel : virtual public Animal { };
class SheepCamel : public Sheep, public Camel{ }; { SheepCamel S; S.m_Age 20; S.Sheep::m_Age 30; S.Camel::m_Age 50; cout Sheep类中 S.Sheep::m_Age endl;// 50 cout Camel类中 S.Camel::m_Age endl;// 50 cout SheepCamel类中 S.m_Age endl; // 50 } 此时数据只有一份类似静态变量无论是用子类调用还是父类调用都是共享同一份数据。也可以理解为不管给哪个赋值都是给同一个变量赋值所以最后等于后赋的值
底层原理
我们可以通过对象模型来直观理解
在visual studio code 下利用开发人员命令提示工具查看对象模型我使用的是vs2022
1.找到开发人员命令提示工具 2.输入 cd空格当前源文件的路径若是C盘直接输入即可若是F盘先 F转入F盘
当前源文件的路径获取方法 最后输入到开发人员命令提示工具 输入 cd空格当前源文件的路径 3.输入dir进行查看当前目录是否有当前源文件 4.有当前源文件继续查找当前SheepCamel类的对象模型布局 输入cl /d1 reportSingleClassLayout查找类名 当前源文件名 输入cl /d1 reportSingleClassLayoutSheepCamel 源.cpp 未设置为虚基类时 我们可以发现Sheep类的字节大小为8个字节分别继承于Sheep类、Camel类的成员变量m_Age
的确是继承了两份数据。
设置为虚基类时: 我们可以发现Sheep类的字节大小为12个字节分别是Sheep类的虚基类指针、Camel类的虚基类指针子类继承的m_Age;
此时只继承了一份数据。
总结在虚基类中继承仅有的一份数据存储于子类可以通过 虚基类指针访问子类来修改其数据的值或者 子类对象本身来修改。