C++ 添加虚拟消除错误:类型“基”不是派生类的直接基

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8419120/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 18:32:22  来源:igfitidea点击:

Adding virtual removes the error : type 'base' is not a direct base of derived class

c++inheritancederived-classbase-class

提问by nitin_cherian

Conside the following sample code below:

考虑以下示例代码:

#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;
}

This gives the error:

这给出了错误:

error: type `base' is not a direct base of `derived2'

错误:类型“base”不是“derived2”的直接基数

Why is this error occurring? If i make the base class virtual, the error is no longer there. What is the reason for this?

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

回答by smparkes

Because baseis not a direct base of derived2. You have to give a constructor for your direct bases, derived1in this case.

因为base不是 的直接基础derived2derived1在这种情况下,您必须为您的直接基础提供一个构造函数。

Virtual bases are the exception. They are always initialized in leaf classes, otherwise potentially you get multiple constructor calls for the same base. So if you make basevirtual, not only can you initialize it in derived2, you must.

虚拟基地是个例外。它们总是在叶类中初始化,否则可能会为同一个基类调用多个构造函数。因此,如果您进行base虚拟化,不仅可以在derived2.

The issue arises when you have a derivation graph that is not a tree. IBMhas a pretty picture. If you don't make the base (Vin the example) virtual (everywhere) you'll have multiple copies. If you do make it virtual everywhere, you'll only have one copy, but then the direct children can not run the constructor (it would run > 1 time) and the leaf class must. For more details, best to search the web.

当您有一个不是树的派生图时,就会出现问题。IBM有一个漂亮的图片。如果您不将基础(V在示例中)设为虚拟(无处不在),您将拥有多个副本。如果你在任何地方都让它成为虚拟的,你将只有一个副本,但是直接子级不能运行构造函数(它会运行 > 1 次)并且叶类必须。更多详情,最好在网上搜索。

回答by parapura rajkumar

Change

改变

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

to

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

This is because you trying to call base1constructor from a grand child derived2.

这是因为您试图从大子衍生 2调用base1构造 函数

If you change the derivation of derived1 from base1 to be virtual. It is ok to call base1 from derived2. More details here.

如果将来自 base1 的衍生 1 的派生更改为虚拟。从derivative2调用base1是可以的。更多细节在这里。

回答by danca

You have derived1 in between. You can only call immediate parents within the initializer list

你已经在两者之间派生了1​​。您只能在初始化列表中调用直接父母