搞清C++虚继承

c++虚继承平时很少用到,看书的时候也就是理解个大概。
这次实践中使用到了虚继承,总算有了具体的印象。

基类thunk怎么在子类对象里堆叠的,咱就不赘述了,反正网上、教科书上到处都有讲。这次咱自己遇到的问题主要是虚继承和普通多重继承没搞清区别。

我有一套虚接口hierarchy.


class View {
   virtual int ID() = 0;
   virtual int Child() = 0;
};

class TextView : public {
   virtual const char* getText() = 0;
};

此处省去代码数百行。。。

之后当我开始做这套虚接口的一组实现时,才发现问题。


class SysView : public View {
    virtual int ID();
    virtual int Child();
};

到这里还是都正常的。


class SysTextView : public SysView, public TextView
{
     virtual const char* getText();
};

当实现这个类时,就会发现其对象无法实例化。因为View下面的虚接口没有实现。咦,不是继承了SysView而SysView实现了View下面的所有虚接口吗?问题没有这么简单。因为这个是多重继承,每个父类都会在子类中产生一个拷贝,所以SysTextView里面就出现了两个View类型的父对象。一个是SysView,一个是TextView。而TextView没有实现View的虚接口,因此这个类整个就都不能实例化了。

解决方案就是必须使用虚继承,让编译器知道,TextView继承的那个View和SysView继承的那个View,是同一个View。则需要修改的代码如下:


class SysView: virtual public View {
///...
};

class TextView : virtual public View {
///...
};

注意SysTextView并不需要对其两个父类进行虚继承,除非hierarchy下面还有对这个类进行多继承的情况出现。

虚继承会影响系统性能,应尽量避免。这里用到这个逻辑,只是为了能够使用工厂方法较为优美地创建出各种不同类型的对象,然后调用其虚接口完成操作。并不是性能瓶颈。呜长久以来一个知识漏洞终于通过一次实践补上了。挺好。