2

I wondering why in c++ can't use parent class constructor for an specific signature, in case that derived class miss that?

For example in below sample, I can't initialize dd object with std::string.

#include <iostream>


class Base
{
    int num;
    std::string s;
public:
    Base(int _num){ num = _num;}
    Base(std::string _s){ s = _s;}
};

class Derived : public Base {
public:
    Derived(int _num):Base(_num){}
};

int main()
{
    Base b(50);
    Derived d(50);
    Base bb("hell");
    Derived dd("hell"); // <<== Error
    return 0;
}

With Inheritance I expect to extend a class and not losing previous functionality but here I feel losing some.

In a more practical example, I create my version of std::string but It doesn't behave like a std::string in some cases :

#include <string>
#include <iostream>


class MyString: public std::string {
public:
    void NewFeature(){/* new feature implementation*/}
};

int main()
{
    MyString s("initialization");   // <<== Error: I expect to initialize with "..."
    cout<<s;                        // <<== Error: I expect to print it like this.
    return 0;
}

Can somebody give some explanation ?

Emadpres
  • 3,466
  • 2
  • 29
  • 44

2 Answers2

9

If you want to inherit the constructors too, you need to tell the compiler in your code:

class Derived : public Base {
  public:
    using Base::Base;  // <- Makes Base's constructors visible in Derived
};

As for "Why do I need to do this?": The cheap answer is: Because the standard says so.

Why it does that is speculation (if you do not ask the committee members themselves). Most likely they wanted to avoid "surprising" or "un-intuitive" code-behavior.

Baum mit Augen
  • 49,044
  • 25
  • 144
  • 182
  • Although `using std::string::std::string` doesn't work, I need the `why` of this problem. why `Inheritance` smells here . – Emadpres Dec 07 '14 at 14:36
  • 1
    @Emadpres See [here](http://coliru.stacked-crooked.com/a/bc7ea27f32f4594c) for a working syntax for `std::string`. (Pretty much what I wrote in the answer. :) ) – Baum mit Augen Dec 07 '14 at 14:45
  • I'm actually surprised. They wrote a special case into the standard to make things like `using std::string::string` work (recall that `std::string` is actually a typedef for a particular specialization of `std::basic_string`...) – T.C. Dec 07 '14 at 14:51
  • I think my compiler (VS2012) use pre-c++11 standard. Thank you for your answer. – Emadpres Dec 07 '14 at 14:52
  • @BaummitAugen How about `cout< – Emadpres Dec 07 '14 at 15:22
  • @Emadpres If `operator<<` should do the same as for `std::string`, no additional work is required (you just call the `operator<<` of `std::string` this way). If it should do something special, you need to add an appropriate overload `std::ostream& (std::ostream&, const MYString&);`. – Baum mit Augen Dec 07 '14 at 15:47
1

I don't have enough rep to flag as duplicate, but Inheriting constructors answers this sufficiently.

Basically, pre-C++11 it was in the standard to not allow constructor inheritance. C++11 has changed this and you can now inherit constructors.

Community
  • 1
  • 1
E. Moritz
  • 51
  • 1
  • 6