-1

Inheriting constructors

Above link said:

In C++03 standard constructors cannot be inherited and you need to inherit them manually one by one by calling base implementation on your own.

So how to do it and bypass it without C++11?

#include <iostream>

using namespace std;


class A {   
    public:
        int x;
        explicit A(int _x) {
        x = _x;
        }
};

class B:A {
    public:
    explicit B(int x) : A(x) { 

    }
};


int main(int argc, char** argv) {
     A a(10);
     B b(11);

     cout << a.x;
     cout << b.x;

return 0;

}

  • Kamil: It means that in your derived C++03 class you have to write a wrapper for each base class constructor, if you want to expose these constructors. – Cheers and hth. - Alf Dec 09 '17 at 18:09
  • unusable comments I think...should I use C++11 anyway? – Kamil Wiśniewski Dec 09 '17 at 18:16
  • @KamilWiśniewski - That's an easy one. If you may, then most certainly do. – StoryTeller - Unslander Monica Dec 09 '17 at 18:20
  • @Kamil - The second answer at your link shows *exactly* how you have to do this in C++03 https://stackoverflow.com/a/347362/597607 – Bo Persson Dec 09 '17 at 18:26
  • 1
    Kamil: You should post your non-working code, with explanation of what you expected (and why), and what it actually did instead. Then the question is how to implement what you expected and wanted, plus why your non-working code didn't do that. – Cheers and hth. - Alf Dec 09 '17 at 18:38
  • @KamilWiśniewski: Code posted (even if that was in a comment that was deleted), that's good. Now, change `class B:A` to `class B: public A`, and it compiles. Add `<< endl` to the output statements and it produces sensible output too. Btw., it would have been nice with that code in the original question. Then it would have been closed as typo / trivial, but better than the downvotes and all, yes? ;-) – Cheers and hth. - Alf Dec 09 '17 at 18:44
  • I post it earlier as comment now its on top so what is the problem? – Kamil Wiśniewski Dec 09 '17 at 18:48
  • Now you've put that in the question, it allows [answers that are more directly helpful to you](https://stackoverflow.com/questions/47731568/inheritance-constructors-without-c11#comment82424365_47731568). For future postings, they can be further improved by including info about what you expected, and what you got instead. – Cheers and hth. - Alf Dec 09 '17 at 18:51
  • Now I see the fault thanks, but I want to know too, If inheritance is public its working of course but what should I do if **int x** in base class will be protected? – Kamil Wiśniewski Dec 09 '17 at 18:53
  • The same. Except in order to output its value you'd need a public member function that provides the value. – Cheers and hth. - Alf Dec 09 '17 at 18:53
  • I think Im little drunk :) I missed that **public** earlier, but anyway thanks for answers. – Kamil Wiśniewski Dec 09 '17 at 19:00

1 Answers1

0

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

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331