gpt4 book ai didi

c++ - 调用虚基类的重载构造函数

转载 作者:可可西里 更新时间:2023-11-01 15:22:11 25 4
gpt4 key购买 nike

是否有一种(实用的)方法可以绕过正常的(虚拟的)构造函数调用顺序?

示例:

class A
{
const int i;

public:
A()
: i(0)
{ cout << "calling A()" << endl; }

A(int p)
: i(p)
{ cout << "calling A(int)" << endl; }
};

class B
: public virtual A
{
public:
B(int i)
: A(i)
{ cout << "calling B(int)" << endl; }
};

class C
: public B
{
public:
C(int i)
: A(i), B(i)
{ cout << "calling C(int)" << endl; }
};

class D
: public C
{
public:
D(int i)
: /*A(i), */ C(i)
{ cout << "calling D(int)" << endl; }
};


int main()
{
D d(42);
return 0;
}

输出:

calling A()
calling B(int)
calling C(int)
calling D(int)

我想要的是这样的:

calling A(int)
calling B(int)
calling C(int)
calling D(int)


如你所见,这里涉及到虚继承,导致D的构造函数先调用了A的构造函数,但由于没有提供参数,所以调用了A()。 const int i 需要初始化,所以我遇到了问题。

我想做的是隐藏 C 的继承细节,这就是为什么我正在寻找一种方法来避免在 D 的(和每个派生的)构造函数的初始化列表中调用 A(i)。 [编辑] 在这种特定情况下,我可以假设只有 C 的非虚拟单继承子类(因为 D 是一个)。 [/编辑]

[编辑]

Virtual base classes are initialized before any non-virtual base classes are initialized, so only the most derived class can initialize virtual base classes. – James McNellis

这正是重点,我希望最派生类调用虚拟基类构造函数。[/edit]

考虑以下情况(上面的代码示例中未表示):

  A
/ \
B0 B1
\ /
C
|
D

我理解了为什么实例化C的时候C要调用A的ctor(歧义),但是D实例化D的时候为什么要调用呢?

最佳答案

不幸的是,您总是必须从最派生类调用虚拟基类构造函数。

这是因为您是说虚拟基类在所有从它派生的对象实例的类之间共享。由于对于给定的对象实例化,构造函数可能只被调用一次,因此您必须在最派生的类中显式调用构造函数,因为编译器不知道有多少类共享虚拟基(从 The C++ 编程语言第 3 版,第 15.2.4.1 节)。这是因为编译器将从最基类的构造函数开始,一直工作到最派生类。按照标准,直接从虚拟基类继承的类不会调用它们的虚拟基类构造函数,因此必须显式调用它。

关于c++ - 调用虚基类的重载构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3495139/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com