C++继承中的多继承语法与菱形继承

简介: 多继承语法C++允许一个类继承多个类语法:class 子类 :继承方式 父类1 , 继承方式 父类2...多继承可能会引发父类中有同名成员出现,需要加作用域区分C++实际开发中不建议用多继承



多继承语法

C++允许一个类继承多个类

语法:class 子类 :继承方式 父类1 , 继承方式 父类2...

多继承可能会引发父类中有同名成员出现,需要加作用域区分

C++实际开发中不建议用多继承

示例:

classBase1 {

public:

   Base1()

   {

       m_A=100;

   }

public:

   intm_A;

};

classBase2 {

public:

   Base2()

   {

       m_A=200;  //开始是m_B 不会出问题,但是改为mA就会出现不明确

   }

public:

   intm_A;

};

//语法:class 子类:继承方式 父类1 ,继承方式 父类2

classSon : publicBase2, publicBase1

{

public:

   Son()

   {

       m_C=300;

       m_D=400;

   }

public:

   intm_C;

   intm_D;

};

//多继承容易产生成员同名的情况

//通过使用类名作用域可以区分调用哪一个基类的成员

voidtest01()

{

   Sons;

   cout<<"sizeof Son = "<<sizeof(s) <<endl;

   cout<<s.Base1::m_A<<endl;

   cout<<s.Base2::m_A<<endl;

}

intmain() {

   test01();

   system("pause");

   return0;

}

总结: 多继承中如果父类中出现了同名情况,子类使用时候要加作用域

菱形继承

菱形继承概念:

两个派生类继承同一个基类

又有某个类同时继承者两个派生类

这种继承被称为菱形继承,或者钻石继承


菱形继承问题:

  1. 羊继承了动物的数据,驼同样继承了动物的数据,当草泥马使用数据时,就会产生二义性。
  2. 草泥马继承自动物的数据继承了两份,其实我们应该清楚,这份数据我们只需要一份就可以。

示例:

classAnimal

{

public:

   intm_Age;

};

//继承前加virtual关键字后,变为虚继承

//此时公共的父类Animal称为虚基类

classSheep : virtualpublicAnimal {};

classTuo   : virtualpublicAnimal {};

classSheepTuo : publicSheep, publicTuo {};

voidtest01()

{

   SheepTuost;

   st.Sheep::m_Age=100;

   st.Tuo::m_Age=200;

   cout<<"st.Sheep::m_Age = "<<st.Sheep::m_Age<<endl;

   cout<<"st.Tuo::m_Age = "<<  st.Tuo::m_Age<<endl;

   cout<<"st.m_Age = "<<st.m_Age<<endl;

}

intmain() {

   test01();

   system("pause");

   return0;

}

vbptr全称:virtual base pointer虚基类指针,指向vbtable ,virtual base table 虚基类列表。

1.jpg

使用了虚继承后对比未使用虚继承解决菱形继承

2.jpg

总结:

  • 菱形继承带来的主要问题是子类继承两份相同的数据,导致资源浪费以及毫无意义
  • 利用虚继承可以解决菱形继承问题


目录
相关文章
|
17天前
|
C++
C++(二十)继承
本文介绍了C++中的继承特性,包括公有、保护和私有继承,并解释了虚继承的作用。通过示例展示了派生类如何从基类继承属性和方法,并保持自身的独特性。此外,还详细说明了派生类构造函数的语法格式及构造顺序,提供了具体的代码示例帮助理解。
|
1月前
|
编译器 C++ 容器
C++语言的基本语法
想掌握一门编程语言,第一步就是需要熟悉基本的环境,然后就是最重要的语法知识。 C++ 程序可以定义为对象的集合,这些对象通过调用彼此的方法进行交互。现在让我们简要地看一下什么是类、对象,方法、即时变量。 对象 - 对象具有状态和行为。例如:一只狗的状态 - 颜色、名称、品种,行为 - 摇动、叫唤、吃。对象是类的实例。 类 - 类可以定义为描述对象行为/状态的模板/蓝图。 方法 - 从基本上说,一个方法表示一种行为。一个类可以包含多个方法。可以在方法中写入逻辑、操作数据以及执行所有的动作。 即时变量 - 每个对象都有其独特的即时变量。对象的状态是由这些即时变量的值创建的。 完整关键字
46 2
|
1月前
|
安全 Java 编译器
|
2月前
|
Java C++ 运维
开发与运维函数问题之C++中有哪些继承方式如何解决
开发与运维函数问题之C++中有哪些继承方式如何解决
22 0
|
2天前
|
编译器 C++
C++ 类构造函数初始化列表
构造函数初始化列表以一个冒号开始,接着是以逗号分隔的数据成员列表,每个数据成员后面跟一个放在括号中的初始化式。
43 30
|
17天前
|
存储 编译器 C++
C ++初阶:类和对象(中)
C ++初阶:类和对象(中)
|
1月前
|
存储 安全 编译器
【C++】类和对象(下)
【C++】类和对象(下)
【C++】类和对象(下)
|
17天前
|
C++
C++(十六)类之间转化
在C++中,类之间的转换可以通过转换构造函数和操作符函数实现。转换构造函数是一种单参数构造函数,用于将其他类型转换为本类类型。为了防止不必要的隐式转换,可以使用`explicit`关键字来禁止这种自动转换。此外,还可以通过定义`operator`函数来进行类型转换,该函数无参数且无返回值。下面展示了如何使用这两种方式实现自定义类型的相互转换,并通过示例代码说明了`explicit`关键字的作用。
|
17天前
|
存储 设计模式 编译器
C++(十三) 类的扩展
本文详细介绍了C++中类的各种扩展特性,包括类成员存储、`sizeof`操作符的应用、类成员函数的存储方式及其背后的`this`指针机制。此外,还探讨了`const`修饰符在成员变量和函数中的作用,以及如何通过`static`关键字实现类中的资源共享。文章还介绍了单例模式的设计思路,并讨论了指向类成员(数据成员和函数成员)的指针的使用方法。最后,还讲解了指向静态成员的指针的相关概念和应用示例。通过这些内容,帮助读者更好地理解和掌握C++面向对象编程的核心概念和技术细节。
|
30天前
|
存储 算法 编译器
c++--类(上)
c++--类(上)