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...
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.