Вызывается ли конструктор базового класса и деструктор с производными?

У меня есть класс под названием MyBase, который имеет конструктор и деструктор:

class MyBase
{
public:
    MyBase(void);
    ~MyBase(void);
};

и у меня есть класс Banana, который расширяет MyBase так:

class Banana:public MyBase
{
public:
    Banana(void);
    ~Banana(void);
};

Выполняет ли реализация нового конструктора и деструктора в банане переопределить MyBase, или они все еще существуют, и вызвать вызов до или после выполнения конструктора/деструктора Banana?

Спасибо, и мои извинения, если мой вопрос кажется глупым.

Ответ 1

Он должен сказать

class Banana : public MyBase
{
public:
    Banana(void);
    ~Banana(void);
};

Конструктор производного класса вызывается после конструктора базового класса. Деструкторы вызываются в обратном порядке.

Ответ 2

Базовый конструктор всегда вызывается перед производным конструктором. Деструктор базы будет вызван после Dervided destructor.

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

Если вы определяете другие конструкторы, но не по умолчанию, и не указываете в Derived конструкторе, какой из них выполнить, он попробует значение по умолчанию, которое не существует, и приведет к сбою компиляции.

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

Ответ 3

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

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

virtual ~MyBase() { ... }

Ответ 4

Конструкторы и деструкторы - это специальные функции-члены. В общем, вы будете читать везде, что конструкция начинается с наименее производного типа в иерархии вплоть до самого производного типа. На самом деле это порядок выполнения конструктора, но не запуск конструкции.

Порядок выполнения списка инициализации конструкторов гарантирует, что, хотя конструктор большинства производных объектов будет первым конструктором, который начнет выполнение, будет последним конструктором завершить

Когда вы создаете экземпляр объекта, наиболее производный конструктор, соответствующий конструкторскому вызову, вызывается первым. Появится список инициализации совпадающего большинства производных конструкторов, а списки инициализации имеют фиксированный порядок: сначала вызываются конструкторы базовых классов по порядку или появлению в списке наследования. Затем конструкторы атрибутов-членов вызываются в том порядке, в котором они появляются в объявлении класса (а не в порядке, в котором они отображаются в списке инициализации). После завершения всего списка инициализации (на каждом уровне) выполняется блок body конструктора, после чего завершается вызов конструктора.

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

Деструкторы отличаются особым образом: они не могут быть переопределены. Когда вы вызываете самый производный деструктор класса, он завершает выполнение тела деструктора, после чего все деструкторы атрибутов участника будут вызываться в обратном порядке создания. После того, как самый производный деструктор завершил и так сделал деструкторы членов самого производного объекта, деструктор его самых прямых оснований начнется в обратном порядке построения, будут выполняться тела деструктора, затем член атрибутов деструкторов и т.д. В конце будут уничтожены все построенные элементы.

Деструкторы для полиморфных классов должны быть виртуальными

Описание разрушения начинается с обращения к самому производному деструктору. Этого можно достичь, вызвав delete указатель на наиболее производный тип, когда автоматический объект выходит за пределы области видимости или когда объект delete d через базовый класс, деструктор которого является виртуальным.

Если вы забыли добавить ключевое слово destructor в базовый класс и попытаетесь удалить производный объект с помощью указателя на базу, вы вызовете базовый деструктор напрямую, а это означает, что все под-объекты ниже типа указателя в иерархия не будет надлежащим образом уничтожена. Все иерархии наследования, в которых вы удаляете объекты с помощью указателей на базовый тип должны иметь виртуальные деструкторы. Как правило, если у вас уже есть какой-либо виртуальный метод, стоимость создания виртуального деструктора ничтожно мала и является безопасной сетью. Многие руководства по кодированию обеспечивают, чтобы деструкторы в иерархиях наследования были виртуальными. Некоторые доходят до того, что запрашивают все деструкторы как виртуальные. Это имеет целью избежать возможных утечек ресурсов за счет добавления vtable для всех типов и указателя vtable для всех объектов.

Ответ 5

Конструкторы называются сверху вниз в дереве наследования. Это значит, что производный конструктор может рассчитывать на то, что базовый объект будет полностью инициализирован, прежде чем он попытается использовать любые свойства базы.

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

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

Ответ 6

Вам не хватает типа наследования:

Изменить

class Banana:MyBase

To:

class Banana: public MyBase

Что касается

выполняется ли внедрение нового конструктор и деструктор в Банане переопределить MyBase, или они все еще существуют, и их называют или после бананового конструктора/ Выполняется деструктор?

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

Возьмем этот пример:

class RottenBanana : public Banana

Цепочка наследования теперь RottenBanana → Banana → MyBase

Конструкторы этого класса будут называться начиная с MyBase, затем с Banana и затем вызывая RottenBanana.

Ответ 7

Если вы создаете экземпляр объекта EEGModeRGB (который подключен к трехцветному светодиоду), то сразу же удалите его, вы увидите цвета Синий, Зеленый, Желтый и Красный, в течение одной секунды каждый - в этом порядке.

class EEGMode {
public:

   EEGMode()  { setAllPixelsToColor(BLUE); delay(1000); }
   virtual ~EEGMode()  { setAllPixelsToColor(RED); delay(1000); }

};


class EEGModeRGB : public EEGMode {
public:

    EEGModeRGB()  { setAllPixelsToColor(GREEN);  delay(1000); }
    virtual ~EEGModeRGB()  { setAllPixelsToColor(YELLOW); delay(1000); }

};