C++虚继承小结

本文探讨了C++中的虚拟继承机制,旨在解决多重继承中的重复基类问题。通过实例展示了虚继承如何影响类的对象布局,以及对构造函数调用顺序的影响。文章深入分析了虚继承在内存布局、类大小变化以及构造过程中的作用,帮助读者更好地理解和应用虚继承。
摘要由CSDN通过智能技术生成

虚拟继承是C++语言中一个非常重要但是又比较生僻的存在,它的定义非常简单,但是对于理解C++的继承机制却是非常有用的。笔者最近学习过程中发现对C++的虚拟继承不是很明朗,故在这里对虚继承做个小结。

首先说下遇到的问题吧。代码如下(代码来自于何海涛《程序员面试精选100题第32题)。意图是要设计一个不能被继承的类,类似java中的final。但是又可以生成栈对象,可以像一般的C++类一样使用。

#include<iostream>

using std::endl;

using std::cout;

template <class T> class MakeFinal

{

friend T;

private:

MakeFinal()

{

cout<<"in MakeFinal"<<endl;

}

~MakeFinal(){}

};

class FinalClass: virtual public MakeFinal<FinalClass>

{

public:

FinalClass()

{

cout<<"in FinalClass"<<endl;

}

~FinalClass(){}

};

  class Try: public FinalClass

{

public:

Try()

{

cout<<"in Try"<<endl;

}

};

这样的确使得FinalClass不能被继承了,原因在于类FinalClass是从类MakeFinal<Final>虚继承过来的,在调用Try的构造函数的时候,会直接跳过FinalClass而直接调用MakeFinal<FinalClass>的构造函数。而Try不是MakeFinal<Final>的友元,所以这里就会出现编译错误。但是如果把虚继承改成一般的继承,这里就没什么问题了。笔者对这里的调用顺序不是很明朗,为了对虚继承有彻底的了解,故做个小结。将从下面几个方向进行总结:1、为何要有虚继承;2、虚继承对于类的对象布局的影响;3、虚基类对构造函数的影响;

1、为什么需要虚继承

由于C++支持多重继承,那么在这种情况下会出现重复的基类这种情况,也就是说可能出现将一个类两次作为基类的可能性。比如像下面的情况

                              

#include<iostream>
using std::cout;
using std::endl;
class Base
{
protected:
int value;
public:
Base()
{
cout<<"in Base"<<endl;
}
};
class DerivedA:protected Base
{
public:
DerivedA()
{
cout<<"in DerivedA"<<endl;
}
};
class DerivedB: protected Base
{
public:
DerivedB()
{
cout<<"in DerivedB"<<endl;
}
};
class MyClass:DerivedA,DerivedB
{
public:
MyClass()
{
cout<<"in MyClass"<<value<<endl;
}
};

编译时的错误如下


这中情况下会造成在MyClass中访问value时出现路径不明确的编译错误,要访问数据,就需要显示地加以限定。变成DerivedA::value或者DerivedB::value,以消除歧义性。并且,通常情况下,像Base这样的公共基类不应该表示为两个分离的对象,而要解决这种问题就可以用虚基类加以处理。如果使用虚继承,编译便正常了,类的结构示意图便如下。


虚继承的特点是,在任何派生类中的virtual基类总用同一个(共享)对

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值