Как вызвать конструктор базового класса?
Латли я провел много программирования на Java. Там вы называете класс, который вы унаследовали от С super(); (вы все, наверное знаете, что)
Теперь у меня есть класс В C++, который имеет конструктор по умолчанию, которая принимает несколько аргументов. Пример:
class BaseClass {
public:
BaseClass(char *name); ....
Если я наследую класс, он дает мне предупреждение,что нет подходящего конструктора по умолчанию. Так что есть что-то вроде super() в C++, или мне нужно определить функцию, где я инициализирую все переменные?
6 ответов:
вы делаете это в списке инициализатор конструктора подкласса.
class Foo : public BaseClass { public: Foo() : BaseClass("asdf") {} };конструкторы базового класса, которые принимают аргументы, должны быть вызваны там до инициализации каких-либо членов.
в заголовочном файле определите базовый класс:
class BaseClass { public: BaseClass(params); };затем определите производный класс как наследующий базовый класс:
class DerivedClass : public BaseClass { public: DerivedClass(params); };в исходном файле определите конструктор базового класса:
BaseClass::BaseClass(params) { //Perform BaseClass initialization }по умолчанию производный конструктор вызывает только базовый конструктор по умолчанию без параметров; поэтому в этом примере конструктор базового класса не вызывается автоматически при вызове производного конструктора, но это может быть достигнуто просто путем добавления синтаксис конструктора базового класса после двоеточия (
:). Определите производный конструктор, который автоматически вызывает свой базовый конструктор:DerivedClass::DerivedClass(params) : BaseClass(params) { //This occurs AFTER BaseClass(params) is called first and can //perform additional initialization for the derived class }The
BaseClassконструктор вызывается передDerivedClassконструктор, и те же/разные параметрыparamsпри желании может быть перенаправлен в базовый класс. Это может быть вложено для более глубоких производных классов. Производный конструктор должен вызывать ровно один базовый конструктор. Деструкторы автоматически вызываются в обратном порядке что конструкторы были вызваны.EDIT: существует исключение из этого правила, если вы наследуете от любого
virtualклассов, как правило, для достижения множественное наследование или алмазный наследство. Затем вы должны явно вызвать базовые конструкторы allvirtualбазовые классы и передать параметры явно, в противном случае он будет вызывать только их конструкторы по умолчанию без любые параметры. Смотрите:виртуальное наследование - пропуск конструкторов
вы должны использовать initiailzers:
class DerivedClass : public BaseClass { public: DerivedClass() : BaseClass(<insert arguments here>) { } };Это также то, как вы строите члены вашего класса, которые не имеют конструкторов (или которые вы хотите инициализировать). Все не упомянутые члены будут инициализированы по умолчанию. Например:
class DerivedClass : public BaseClass { public: DerivedClass() : BaseClass(<insert arguments here>) , nc(<insert arguments here>) //di will be default initialized. { } private: NeedsConstructor nc; CanBeDefaultInit di; };порядок, в котором указаны члены, не имеет значения (хотя конструкторы должны быть первыми), но порядок, в котором они будут построены, находится в порядке объявления. Так что
ncвсегда будет построен раньшеdi.
что касается альтернативы super; вы бы в большинстве случаев использовали базовый класс либо в списке инициализации производного класса, либо с помощью
Base::someDataсинтаксис, когда вы выполняете работу в другом месте и производный класс переопределяет члены данных.struct Base { Base(char* name) { } virtual ~Base(); int d; }; struct Derived : Base { Derived() : Base("someString") { } int d; void foo() { d = Base::d; } };
используйте имя базового класса в списке инициализаторов. Инициализатор-список появляется после подписи конструктора перед телом метода и может использоваться для инициализации базовых классов и членов.
class Base { public: Base(char* name) { // ... } }; class Derived : Base { public: Derived() : Base("hello") { // ... } };или, шаблон, используемый некоторыми людьми, чтобы определить "супер" или "база" себя. Возможно, некоторые из людей, которые предпочитают этот метод, являются разработчиками Java, которые переходят на C++.
class Derived : Base { public: typedef Base super; Derived() : super("hello") { // ... } };
Comments