Нужен пример, показывающий, что конструктор по умолчанию не наследуется

Я знаю, что конструктор по умолчанию не наследуется, как указано в 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 по умолчанию наследуется, то пример будет компилироваться / не компилироваться».

Я предпочел бы ответы, где результат (наблюдаемое поведение) отличается от того, что было бы иначе.

6

Решение

Рассматривать:

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) конструктор.

2

Другие решения

Одно возможное отличие: множественное конструирование-наследование от классов с конструкторами по умолчанию. Например:

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, что приводит к двусмысленности.

Я не могу придумать вариант использования для наследования нескольких конструкторов, так что это может быть не идеальный пример, который вы ищете, но это нечто.

3

Вот пример, который может быть получен из следующей функции унаследованных конструкторов:

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
}
1
По вопросам рекламы [email protected]