不要为虚基类使用默认构造函数

时间:2016-08-03 16:07:40

标签: c++

我正在查看Understanding virtual base classes and constructor calls并且我理解最派生的类将直接调用顶级类的默认构造函数。但有没有办法不调用顶级默认构造函数?

我的问题的一个例子,

#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)是否有任何方法可以完成,以减轻必须这样做的最多派生类?

1 个答案:

答案 0 :(得分:1)

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