不对虚拟基类使用默认构造函数

Not to use default constructor for virtual base class

本文关键字:默认 构造函数 基类 虚拟      更新时间:2023-10-16

我研究了理解虚拟基类和构造函数调用,我了解到最派生的类将直接调用顶级基类默认构造函数。但是有没有一种方法可以不调用top-base默认构造函数呢?

我的问题的一个例子,

#include <iostream>
#include <cstdint>
////// BEGIN LIBRARY CODE
class A
{
public:
    A()
    {
        std::cout << __PRETTY_FUNCTION__ << 'n';
    }
    A(int)
    {
        std::cout << __PRETTY_FUNCTION__ << 'n';
    }
};
class B : virtual public A
{
public:
    B()
    {
        std::cout << __PRETTY_FUNCTION__ << 'n';
    }
};
class C: virtual public A
{
public:
    C()
    {
        std::cout << __PRETTY_FUNCTION__ << 'n';
    }
};
class D: public B, public C
{
public:
    D(int x) : A(x), B(), C() // ok. works as expected
    {
        std::cout << __PRETTY_FUNCTION__ << 'n';
    }
};
////// END LIBRARY CODE

////// USER CODE BEGINS
class E: public D
{
public:
    E() : D(42) // problem, invokes A(), not A(int)
    {
        std::cout << __PRETTY_FUNCTION__ << 'n';
    }
    E(int x) : D(x) // same problem
    {
        std::cout << __PRETTY_FUNCTION__ << 'n';
    }
};
////// USER CODE ENDS
int main()
{
    D d(1);
    E e1,e2(42);
}

输出

A::A(int)
B::B()
C::C()
D::D(int)
A::A()
B::B()
C::C()
D::D(int)
E::E()
A::A()
B::B()
C::C()
D::D(int)
E::E(int)

问题:

我希望E只关心D的构造。但从一开始的解释来看,如果我不在下面添加A::A(int),无论我如何更新D类,我都将始终使用默认构造函数

E() : A(42), D(42) // works, but undesirable
{
    std::cout << __PRETTY_FUNCTION__ << 'n';
}
E(int x) : A(x), D(x) // this works, but undesirable
{
    std::cout << __PRETTY_FUNCTION__ << 'n';
}

简而言之,我不希望用户代码class E扩展库代码class D必须指定class A的构造参数,因此…

  • 有没有什么方法可以由继承链中的"中间"类(如我上面的例子中的D类)来完成,以减轻派生类最多的情况

顶级类的构造函数调用所有虚拟基的构造函数。但这与为直接的非虚拟基调用构造函数没有什么不同:如果你放入显式构造函数调用,编译器就会使用它;如果不这样做,它将使用默认构造函数。所以答案是否定的,如果默认构造函数不合适,你就无法避免从E.调用A的构造函数