栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

再聊C++多重继承之菱形继承

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

再聊C++多重继承之菱形继承

菱形继承的问题和内存布局
class Base
{
public:
	Base(int){ std::cout << "Base()" << std::endl; };
    ~Base(){ std::cout << "~Base()" << std::endl; };
protected:
    int n;
};

class A : public Base
{
public:
	A(int a):Base(a){ std::cout << "A()" << std::endl; };
    ~A(){ std::cout << "~A()" << std::endl; };
protected:
    int a;
};

class B : public Base
{
public:
	B(int b):Base(b){ std::cout << "B()" << std::endl; };
    ~B(){ std::cout << "~B()" << std::endl; };
protected:
    int b;
};

class C : public A,public B
{
public:
	C(int c):Base(c),A(c),B(c){ std::cout << "C()" << std::endl; };
    ~C(){ std::cout << "~C()" << std::endl; };
protected:
    int c;
};

class A继承自class Base,将Base::n继承下来,class B继承自class Base,也将Base::n继承下来

最后,class C将class A和class B的内容继承下来,这样一来,class C相当于继承了两份Base::n

这样class C的内存布局中会多余出Base::n,假如n占用了特别大的空间,无疑是对内存的浪费,效率低下。

使用虚继承解决菱形继承内存浪费问题
class A : virtual public Base
{
public:
	A(int a):Base(a){ std::cout << "A()" << std::endl; };
    ~A(){ std::cout << "~A()" << std::endl; };
protected:
    int a;
};

class B : virtual public Base
{
public:
	B(int b):Base(b){ std::cout << "B()" << std::endl; };
    ~B(){ std::cout << "~B()" << std::endl; };
protected:
    int b;
};

当进行虚继承时,虚基类的数据将会被放在内存布局的最后面,并且在原位置补充一个vbptr,指向内存布局的最后面。

这样保证虚基类的数据在对象内存上只有一份拷贝。

总结

菱形继承比较浪费内存,一般出现菱形继承的现象首先考虑设计上的问题,如果设计上的问题没法儿解决,那么使用虚继承进行处理。

菱形继承一般是个比较糟糕的设计,不推荐使用,但是作为学习者,有必要进行了解。

补充:

Base::n将由class C进行初始化,不是class A,也不是class B.

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/887252.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号