简体   繁体   中英

Not to use default constructor for virtual base class

I was looking at Understanding virtual base classes and constructor calls and I understand that the most derived class will call the top-base class default constructor directly. But is there a way not to call top-base default constructor?

One example for my problem,

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

Output

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)

Problem:

I want E to only care about D construction. But from the explanation in the beginning, if I don't add A::A(int) below, I will always use default constructor no matter how I update class 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';
}

In short, I don't want the user-code class E extending the library code class D to have to specify class A construction parameters so...

  • Is there any way it can be done by a "middle" class in the inheritance chain such as class D in my example above, to alleviate the most-derived classes from having to do so?

The constructor for the top-level class calls the constructors for all virtual bases. But that's no different from calling constructors for direct non-virtual bases: if you put in an explicit constructor call, that's what the compiler will use; if you don't, it will use the default constructor. So the answer is no, if the default constructor isn't appropriate, you can't avoid calling A's constructor from E.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM