添加虚拟删除错误:类型'base'不是派生类的直接基础

nit*_*ian 5 c++ inheritance base-class derived-class

请考虑以下示例代码:

#include <iostream>

using namespace std;

class base
{
   public:
      base()
      {
         cout << "ctor in base class\n";
      }
};

class derived1 : public base
{
   public:
      derived1()
      {
         cout <<"ctor in derived1 class\n";
      }
};

class derived2 : public derived1
{
   public:
      derived2() : base()
      {
         cout << "ctor in derived2 class\n";
      }
};

int main()
{
   derived2 d2obj;
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

这给出了错误:

错误:类型`base'不是`derived2'的直接基础

为什么会出现此错误?如果我将基类设为虚拟,则错误不再存在.这是什么原因?

smp*_*kes 8

因为base不是直接的基础derived2.derived1在这种情况下,您必须为您的直接基础提供构造函数.

虚拟基地是例外.它们总是在叶类中初始化,否则可能会为同一个基础获得多个构造函数调用.因此,如果你制作base虚拟产品,不仅可以将其初始化derived2,还必须.

如果您的派生图不是树,则会出现此问题.IBM有一个漂亮的图片.如果您没有使基础(V在示例中)虚拟(在任何地方),您将拥有多个副本.如果你确实在任何地方使它成为虚拟,那么你将只有一个副本,但是直接子节点不能运行构造函数(它将运行> 1次)并且叶类必须.有关详细信息,最好搜索网络.


par*_*mar 6

改变

class derived2 : public derived1
{
   public:
      derived2() : base()
      {
         cout << "ctor in derived2 class\n";
      }
};
Run Code Online (Sandbox Code Playgroud)

class derived2 : public derived1
{
   public:
      derived2() : derived1()
      {
         cout << "ctor in derived2 class\n";
      }
};
Run Code Online (Sandbox Code Playgroud)

这是因为您尝试从孙子 returned2调用base1构造函数。

如果将衍生1从base1的派生更改为虚拟的。从derivative2调用base1就可以了。更多详细信息请参见此处。