Я знаю, что конструктор по умолчанию не наследуется, как указано в n3337.
И там есть пример:
struct B2 {
B2(int = 13, int = 42);
};
struct D2 : B2 {
using B2::B2;
};
С довольно хорошим объяснением:
Набор кандидатов унаследованных конструкторов в
D2
заB2
является... —B2(int = 13, int = 42) —B2(int = 13) —B2()
И самое главное:
Набор конструкторов присутствует в
D2
является
—D2()
, неявно объявленный конструктор по умолчанию, не наследуется
Для меня этот пример не показывает разницы, в том смысле, что даже если этот самый конструктор был унаследован — его поведение не отличалось от неявно объявленного конструктора по умолчанию.
Мне нужен пример, показывающий разницу в способе, который можно легко понять, скажем, для аудитории, знакомой с C ++ 03, но желающей изучать C ++ 11.
[ОБНОВИТЬ]
Все ответы (включая мои собственные) являются добрымиесли c-tor по умолчанию наследуется, то пример будет компилироваться / не компилироваться».
Я предпочел бы ответы, где результат (наблюдаемое поведение) отличается от того, что было бы иначе.
Рассматривать:
struct foo
{
foo() {}
foo(int) {}
};
struct bar : foo
{
using foo::foo;
};
int main()
{
bar b;
}
Это компилируется: с bar
не имеет пользователь объявлена конструкторы, конструктор по умолчанию будет объявлен неявно.
struct foo
{
foo() {}
foo(int) {}
};
struct bar : foo
{
using foo::foo;
bar(double) {}
};
int main()
{
bar b;
}
Это не компилируется. Конструктор по умолчанию не наследуется и не объявляется неявно, так как существует bar(double)
конструктор.
Одно возможное отличие: множественное конструирование-наследование от классов с конструкторами по умолчанию. Например:
struct A { A(int=0); };
struct B { B(double=3.14); };
struct C : A, B {
using A::A;
using B::B;
};
C c;
Если конструкторы по умолчанию были унаследованы, C
унаследует один от обоих A
а также B
, что приводит к двусмысленности.
Я не могу придумать вариант использования для наследования нескольких конструкторов, так что это может быть не идеальный пример, который вы ищете, но это нечто.
Вот пример, который может быть получен из следующей функции унаследованных конструкторов:
12.9 Наследование конструкторов
[…]
4) Объявленный конструктор имеет тот же доступ, что и соответствующий конструктор в X.
Поэтому я предлагаю иметь защищенный конструктор по умолчанию в базе:
class Base {
protected:
Base(int) {}
Base() = default;
};
Если этот конструктор был производным, то производный класс не может быть создан, поскольку производный конструктор будет иметь защищенный доступ. Если не получено — тогда по умолчанию неявно объявленный конструктор имеет открытый доступ:
struct Derived : Base {
using Base::Base;
};
int main() {
Derived d1{}; // not inherited, default constructor is public
Derived d2{1}; // not compiling since this c-tor is inherited, thus protected
}