欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 焦点 > C++之多继承

C++之多继承

2024/10/23 4:22:01 来源:https://blog.csdn.net/a20040518/article/details/142973397  浏览:    关键词:C++之多继承

普通的继承中,子类的虚表是从父类拷贝过来的,子类新增加的特有的虚函数,会添加在这个虚表里。参考文章:CSDN

多继承

问:如果A1、A2中有相同的虚函数,覆盖谁的?

答案:覆盖A1的

多继承还存在一种特殊情况——菱形继承:即此时A1、A2有一个公共的父类。

菱形继承(钻石继承)

继承向上的二义性:

例:Base类中有属性m,我们在Base1的构造函数中将m的值改成2, 在Base2的构造函数中将m的值改成3,那么当Derived中想使用m时,我们取2还是取3?答案是不知道的,在程序中这种情况也是通过不了编译的。为了解决多继承中的菱形继承问题,下面介绍虚继承来解决这一问题。

虚继承

目的:主要解决多继承中的菱形继承问题

class A
{
public:virtual void vfun(){}
};
class B:virtual public A
{
public:virtual void vfun1(){}
};//B包含两个虚表

虚继承特性:

  • 父类和子类在空间上一种倒置关系(与普通继承相比)
  • 当子类有特有的虚函数时,会有自己的虚表,就会有自己的虚指针
  • 子类存在指向虚基类(虚继承里面的基类)的虚基表,子类会有虚基表的指针vbptr,它指向这个虚基表,虚基表里面的内容是指向自己及虚基类的地址偏移量
  • 对于虚基类的初始化由最底层的派生类负责

虚继承解决菱形继承问题方案

1.先虚继承,再多继承 

2.先虚继承,再虚多继承 

重点掌握虚继承特性所占内存空间大小

#include<iostream>
using namespace std;class Base
{
public:Base(int i) { cout << "B()" << " "; }virtual void vfun() {}int a;
};
class Base1:virtual public Base
{
public:Base1(int i): Base(i) { cout << "B1()" << " "; }virtual void vfun1() {}int b;
};
class Base2 :virtual public Base
{
public:Base2(int i) : Base(i) { cout << "B2()" << " "; }virtual void vfun2() {}int c;
};
//1.先虚继承,再多继承
class Derived1 :public Base1, public Base2
{
public:Derived1(int i) :Base1(i), Base2(i), Base(i) { cout << "D1()" << " "; }virtual void vfun3() {}int d;
};
//2.先虚继承,再虚多继承
class Derived2 :virtual public Base1, virtual public Base2
{
public:Derived2(int i) :Base1(i), Base2(i), Base(i) { cout << "D2()" << " "; }virtual void vfun4() {}int e;
};
int main()
{//测试所占内存大小Derived1 d1(1);cout << sizeof(d1) << endl;//B() B1() B2() D1() 36Derived2 d2(1);cout << sizeof(d2) << endl;//B() B1() B2() D2() 44return 0;
}

如有问题,欢迎交流指正!

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com