Почему C ++ не использует конструктор родительского класса?

Мне интересно, почему в С ++ нельзя использовать конструктор родительского класса для конкретной сигнатуры, если этот производный класс пропустил это?

Например, в примере ниже я не могу инициализировать объект dd с помощью 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;
}

С наследованием я ожидаю расширить класс и не потерять предыдущую функциональность, но здесь я чувствую потерю некоторых.

В более практическом примере я создаю свою версию std::string, но в некоторых случаях она не ведет себя как std::string:

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

Может кто-нибудь дать объяснение?


person Emadpres    schedule 07.12.2014    source источник


Ответы (2)


Если вы хотите унаследовать и конструкторы, вам нужно указать компилятору в своем коде:

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

Что касается «Зачем мне это нужно?»: дешевый ответ: так сказано в стандарте.

Почему это происходит - предположение (если вы не спросите самих членов комитета). Скорее всего, они хотели избежать «неожиданного» или «неинтуитивного» поведения кода.

person Baum mit Augen    schedule 07.12.2014
comment
Хотя using std::string::std::string не работает, мне нужно why этой проблемы. почему Inheritance здесь пахнет. - person Emadpres; 07.12.2014
comment
@Emadpres См. здесь рабочий синтаксис для std::string. (Примерно то, что я написал в ответе. :)) - person Baum mit Augen; 07.12.2014
comment
Я действительно удивлен. Они написали специальный случай в стандарте, чтобы заставить работать такие вещи, как using std::string::string (напомним, что std::string на самом деле является typedef для конкретной специализации _3 _...) - person T.C.; 07.12.2014
comment
Я думаю, что мой компилятор (VS2012) использует стандарт pre-C ++ 11. Спасибо за ваш ответ. - person Emadpres; 07.12.2014
comment
@BaummitAugen Как насчет cout<<s;. Я должен сделать еще какую-нибудь работу, чтобы она работала и так далее? - person Emadpres; 07.12.2014
comment
@Emadpres Если operator<< должен делать то же самое, что и для std::string, никаких дополнительных действий не требуется (вы просто вызываете operator<< из std::string таким образом). Если он должен делать что-то особенное, вам нужно добавить соответствующую перегрузку std::ostream& (std::ostream&, const MYString&);. - person Baum mit Augen; 07.12.2014

У меня недостаточно репутации, чтобы пометить как дубликат, но наследование конструкторов на это достаточно ответит.

По сути, до C ++ 11 стандарт не разрешал наследование конструкторов. C ++ 11 изменил это, и теперь вы можете наследовать конструкторы.

person E. Moritz    schedule 07.12.2014