【问题标题】:Multiple level of inheritance and calling base constructors in c++c++ 中的多级继承和调用基构造函数
【发布时间】:2025-12-09 20:25:01
【问题描述】:

我有以下构成多级继承模型的类。

class CavPkoTest : virtual public CavTest
{
public:
    CavPkoTest() : CavTest{CAV_TEST_ID_PKO}, NpBaseTest{CAV_TEST_ID_PKO, MODULE_CAV_TEST} {}
}
class CavTest : virtual public NpBaseTest
{
public:
    CavTest(uint16_t p_testId) : NpBaseTest{p_testId, MODULE_CAV_TEST} {}
}

class NpBaseTest
{
    uint16_t m_testId;
    uint16_t m_moduleType;
public:
    NpBaseTest(uint16_t p_testId, uint16_t p_moduleType) : m_testId{p_testId}, m_moduleType{p_moduleType} {}
}

我的问题是,当调用CavPkoTest()(叶节点)构造函数时,它会委托调用其父类构造函数CavTest()CavTest() 构造函数被声明为显式调用其父 NpBaseTest() 构造函数。那么,当调用CavTest() 构造函数应该为我做这件事时,为什么我需要从CavPkoTest() 显式调用NpBaseTest() 构造函数呢?

如果我将CavPkoTest() 构造函数声明为:

class CavPkoTest : virtual public CavTest
{
public:
    CavPkoTest() : CavTest{CAV_TEST_ID_PKO} {}
}

仅供参考:CavTestNpBaseTest 类都是抽象基类,因为它们具有 1+ 个纯虚成员函数(由 CavPkoTest 类实现)

【问题讨论】:

  • 所有虚拟基地都被认为是直接基地。您必须从任何级别的任何后代调用它们的构造函数,而不仅仅是直接子代。

标签: c++ inheritance multiple-inheritance


【解决方案1】:

通过虚拟继承,您可以拥有从同一个虚拟基类派生的多个基类。

该虚拟基类子对象必须只初始化一次。因此,派生类必须显式初始化它的语言规则。

如果基类要初始化相同的虚拟基类子对象,他们最终会多次初始化它。

【讨论】:

  • 那么CavTest(uint16_t p_testId) : NpBaseTest{p_testId, MODULE_CAV_TEST} {} 呢?当我必须在子类中再次执行此操作时,我传入MODULE_CAV_TEST 似乎是一个浪费的声明。我的意思是我可以不使用 CavTest 的隐式构造函数吗?
  • @nitimalh CavTest 不知道NpBaseTest 是否已经被初始化,因为可以有多个CavTest 基类子对象并且它们之间只有一个NpBaseTest 共享。跨度>
  • 啊好吧..我明白了,我有点想通了。我不需要在 CavTest 构造函数中传递 MODULE_CAV_TEST 。我可以将其声明为CavTest(uint16_t p_testId) : NpBaseTest{p_testId, 0} {}
  • 顺便说一句,如果我不使用虚拟继承,这会如何改变?
  • @nitimalh 如果您放弃虚拟继承,那么最派生类不需要初始化不是其直接基类的虚拟基类。