To fix the presented code:
Replace class B: A
with class B: public A
to give access to A::x
in main
.
Add << endl
or << '\n'
to each output statement, to get more readable output.
So, the problems with that code had nothing to do with inheriting constructors.
For a C++03 ~equivalent of C++11 constructor inheritance, note first that in C++11 and later you can use argument forwarding to almost get the effect of constructor inheritance. Since the forwarding is imperfect there is a small difference, namely that literal 0
will be forwarded as an int
rvalue and not as a nullpointer (when the formal argument is of pointer type). But in practice it will do:
#include <iostream>
#include <utility> // std::forward
using namespace std;
class A
{
public:
int x;
explicit A(int _x): x{ _x } {}
};
class B:
public A
{
public:
template< class... Args >
explicit B( Args&&... args) : A{ forward<Args>( args )... } {}
};
auto main()
-> int
{
A a{ 10 };
B b{ 11 };
cout << a.x << endl;
cout << b.x << endl;
}
This means that in C++03 you can define a single template class with the necessary boilerplate for constructor argument forwarding. Let's call that Constructor_arg_forwarder_
. Then, with class A
unchanged, the derived class B
can look like this:
class B:
public Constructor_arg_forwarder_<A>
{
public:
template< class Args >
explicit B( Args const& args)
: Constructor_arg_forwarder_<A>( args )
{}
};
But what is Args
then? It is an argument pack class, which is known to the Constructor_arg_forwarder_
class, and must be instantiated in each call of this B
constructor. That instantiation is in C++03 probably best accomplished by a factory function args
, and then the main
function with the instantiations can look like this:
int main()
{
A a( args( 10 ) );
B b( args( 11 ) );
cout << a.x << endl;
cout << b.x << endl;
}
For detailed code (it's a lot of boilerplate code, covering each possible number of arguments, but happily it only needs to be defined once) see my 2010 blog article “C++98 constructor arguments forwarding”.