Зачем моему подклассу C ++ нужен явный конструктор? - PullRequest
11 голосов
/ 10 июля 2010

У меня есть базовый класс, который объявляет и определяет конструктор, но по какой-то причине мой публично производный класс не видит этого конструктора, и поэтому я должен явно объявить конструктор пересылки в производном классе:

class WireCount0 {
protected:
    int m;
public:
    WireCount0(const int& rhs) { m = rhs; }
};

class WireCount1 : public WireCount0 {};

class WireCount2 : public WireCount0 {
public: 
  WireCount2(const int& rhs) : WireCount0(rhs) {}
};

int dummy(int argc, char* argv[]) {
    WireCount0 wireCount0(100);
    WireCount1 wireCount1(100);
    WireCount2 wireCount2(100);
    return 0;
}

В приведенном выше коде мое объявление WireCount1 wireCount1(100) отклонено компилятором («Нет соответствующей функции для вызова WireCount1 :: WireCount1 (int) '»), в то время как мои объявления wireCount0 и wireCount2 подходят.

Я не уверен, что понимаю, почему мне нужно предоставить явный конструктор, показанный в WireCount2.Это потому, что компилятор генерирует конструктор по умолчанию для WireCount1, и этот конструктор скрывает конструктор WireCount0?

Для справки, компилятор i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5659).

Ответы [ 3 ]

14 голосов
/ 10 июля 2010

Конструкторы не наследуются.Вы должны создать конструктор для производного класса.Более того, конструктор производного класса должен вызывать конструктор базового класса.

6 голосов
/ 10 июля 2010

Все производные классы должны вызывать конструктор своего базового класса в той или иной форме.

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

Когда у вас есть что-то вроде этого:

class Class0 {
}

class Class1 : public Class0 {
}

Компилятор фактически генерирует это:

class Class0 {
public:
  Class0(){}
}

class Class1 : public Class0 {
  Class1() : Class0(){}
}

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

class Class0 {
public:
  Class0(int param){}
}

class Class1 : public Class0 {
}

Компилятор больше не генерирует конструктор в Class1 для вызова конструктора базового класса, вы должны явно сделать это самостоятельно.

1 голос
/ 10 июля 2010

Вы должны создать свой базовый класс, прежде чем иметь дело с производным. Если вы создаете свой производный класс с нетривиальными конструкторами, компилятор не может решить, что вызывать для base, поэтому возникает ошибка.

...