Как вызвать конструктор базового класса?



Латли я провел много программирования на Java. Там вы называете класс, который вы унаследовали от С super(); (вы все, наверное знаете, что)



Теперь у меня есть класс В C++, который имеет конструктор по умолчанию, которая принимает несколько аргументов. Пример:



class BaseClass {
public:
BaseClass(char *name); ....


Если я наследую класс, он дает мне предупреждение,что нет подходящего конструктора по умолчанию. Так что есть что-то вроде super() в C++, или мне нужно определить функцию, где я инициализирую все переменные?

614   6  

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 классов, как правило, для достижения множественное наследование или алмазный наследство. Затем вы должны явно вызвать базовые конструкторы all virtual базовые классы и передать параметры явно, в противном случае он будет вызывать только их конструкторы по умолчанию без любые параметры. Смотрите:виртуальное наследование - пропуск конструкторов

вы должны использовать 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; }
};

в C++нет супер (). Вы должны вызвать базовый конструктор явно по имени.

используйте имя базового класса в списке инициализаторов. Инициализатор-список появляется после подписи конструктора перед телом метода и может использоваться для инициализации базовых классов и членов.

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

    Ничего не найдено.