наследование — мы «наследуем» конструкторы в C ++? Каково точное определение «наследования»?

Интересно, почему люди говорят:

Msgstr «Унаследованный класс не наследует конструктор».

Если бы вы могли МОЖЕТ использовать конструктор родительского класса, и конструктор без параметров вызывается автоматически, несмотря ни на что.

Пример:

#include <iostream>
using namespace std;

class A {
private :
int x;
public  :
A () {
cout << "I anyway use parameter-less constructors, they are called always" << endl;
}
A (const int& x) {
this->x = x;
cout << "I can use the parent constructor" << endl;
}
};

class B : public A {
private :
int y;
public  :
B() {

}
B (const int& x, const int& y) : A (x) {
this->y = y;
}
};

int main() {

B* b  = new B(1,2);
B* b1 = new B();
return 0;
}

http://ideone.com/e.js/6jzkiP

Так правильно ли говорить, что конструкторы наследуются в c ++? Каково точное определение «унаследовать» в языках программирования?

Заранее спасибо.

2

Решение

Что они имеют в виду, тот конструктор подписи не наследуются.

В вашем примере B не имеет конструктора, принимающего const int& хотя его базовый класс делает. В этом смысле он не «унаследовал» конструктор (но все же может использовать его).

3

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

Интересно, почему люди говорят: «Унаследованный класс не наследует конструктор».

Возможно, лучше всего это проиллюстрировать на примере:

struct Foo
{
Foo(int, int) {}
};

struct Bar : Foo
{
};

Это означает, что нет Bar::Bar(int, int) конструктор, который вы можете вызвать, несмотря на существование конструктора с тем же списком параметров в базовом классе. Таким образом, вы не можете сделать это:

Bar b(42, 42);

В C ++ 11 вы можете на самом деле инетить конструкторы, но вы должны быть откровенными об этом:

struct Bar : Foo
{
using Foo::Foo;
};

Теперь вы можете сказать Bar b(42, 42);

1

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

В C ++ 11 один Можно наследовать конструкторы: Что такое наследование конструктора?

Другой подход к обходу «прокси-конструкторов» в C ++ < 11: Как определить разные типы для одного и того же класса в C ++

1

Я думаю, что они имеют в виду:

struct A {
A(int, int) { }
};

struct B : public A {
};

int main()
{
A a(1, 2); // ok
B b(1, 2); // error
}

Для сравнения с «не специальными» функциями-членами:

struct A {
void f() { }
};

struct B : public A {
};

int main()
{
A a;
B b;
a.f(); // ok
b.f(); // ok too
}

Но, конечно же, изнутри B Вы можете позвонить доступным A конструкторы (как это делают автоматически сгенерированные). То же самое для деструктора.


Обратите внимание, что в C ++ 11 вы можете использовать функцию «наследования конструкторов»:

struct A {
A(int, int) { }
};

struct B : public A {
using A::A;
};

int main()
{
A a(1, 2); // ok
B b(1, 2); // ok now
}
1

В вашем примере конструктор по умолчанию (как вы говорите, «без параметров») действительно вызывает конструктор A по умолчанию, но это не означает, что B «унаследовал» этот конструктор, только то, что он «имеет к нему доступ». То есть конструктор A по умолчанию доступен изнутри B, но он недоступен извне (никто не может использовать конструктор A по умолчанию извне для создания экземпляра B).

Другой способ взглянуть на это — спросить, что разочаровывает конструкторов и наследование в C ++? Обычный ответ некоторых людей (включая меня) состоит в том, что не существует автоматического средства, позволяющего «проходное» конструирование базовых классов, принимающее аргументы от конструкторов производных классов, без явного объявления и определения последних.

0
По вопросам рекламы [email protected]