Почему конструкторы C ++ не наследуются? - PullRequest
5 голосов
/ 15 июля 2011

Почему в этом коде необходим транзитный конструктор Child? Я думаю, что это не так, но компилятор (gcc и VS2010) жалуется, когда я его удаляю. Есть ли элегантный обходной путь? Просто кажется бессмысленным вставлять эту прокладку в дочерние классы.

class Parent
{
public:
  Parent(int i) { }
};

class Child : public Parent
{
public:
  Child(int i) : Parent(i) { }
};

int main()
{
  Child child(4);
  return 0;
}

Ответы [ 7 ]

12 голосов
/ 15 июля 2011

Поскольку следующее совершенно верно:

class Parent
{
public:
    Parent(int i) { }
};

class Child : public Parent
{
public:
    Child() : Parent(42) { }
};

Как компилятор может догадаться, хотите ли вы, чтобы у производного потомка был перенаправленный конструктор?А в случае множественного наследования набор конструкторов из двух типов может не совпадать;при пересылке конструктора из базового класса A, какой конструктор в базовом классе B должен называться?

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

4 голосов
/ 15 июля 2011

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

В вашем случае класс Parent не имеет такого конструктора, компилятор не будет знать, какое значение использовать для i.

Не указание конструктора в классе Child означает, что конструктор по умолчанию в классе Parent будет вызван, но его не существует.


Я не пробовал, но взглянул на этот раздел C ++ 0x FAQ . У меня сложилось впечатление, что вы просите, возможно в C ++ 0x.

3 голосов
/ 15 июля 2011

Это потому, что в C ++ у вас есть множественное наследование.В следующем примере, какой конструктор должен быть унаследован?

class Parent1
{
public:
  Parent1(int i) { }
};

class Parent2
{
public:
  Parent2(int i) { }
};

class Child : public Parent1, public Parent2
{
};
1 голос
/ 20 марта 2018

Есть ли элегантный обходной путь?

Начиная с C ++ 11, вы можете использовать , используя объявление , чтобы наследовать конструкторы (не включая конструкторы по умолчанию, копировать или перемещать) из базы:

class Parent
{
public:
  Parent(int i) { }
};

class Child : public Parent
{
public:
  using Parent::Parent; // inherits Parent(int)
};

int main()
{
  Child child(4);
  return 0;
}
1 голос
/ 15 июля 2011

Вот еще один случай

class Parent
{
public:
  Parent(int i) {this.i = i; }
  Parent() {this.i = 0;}
private:
  int i;
};

class Child : public Parent
{
public:
  Child(int i) : { }
};

int main()
{
  Child child(4);
  return 0;
}

Учитывая, какой конструктор Parent должен быть вызван. Что если Parent определяет конструктор, который принимает long, но не тот, который принимает int? Должен ли компилятор автоматически конвертировать int в long?

Что бы там ни было, разработчики языка выбрали простоту - единственным конструктором, который автоматически вызывается из производного класса, является конструктор по умолчанию (без аргументов или со всеми аргументами по умолчанию). Все остальное нужно явно назвать.

0 голосов
/ 15 июля 2011

Конструкторы должны явно вызываться дочерним конструктором, если вы не хотите использовать конструктор по умолчанию, сгенерированный компилятором, который называется конструктором по умолчанию (конструктор без аргументов). Но, очевидно, в вашем случае вам нужен конструктор, который принимает int, тогда вы должны вызывать его явно.

0 голосов
/ 15 июля 2011

Компилятор автоматически генерирует конструктор по умолчанию, то есть ctr без параметров, но только если вы не определили никаких конструкторов.

В этом случае у вас есть (в родительском), поэтому для вас не задано значение по умолчанию, плюс ребенок нуждается в нем, чтобы он знал, что делать с параметром i, который вы передаете ему.

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