C++: Какой конструктор вызывается первым?

Я смотрел на похожие вопросы, но, похоже, теряюсь. У меня есть простой пример, поэтому, пожалуйста, обратите внимание на следующее:

#include <iostream>
using namespace std;

class Animal
{
  public:
    Animal() {cout << "Animal" << endl;}
};

class Cat : public Animal
{
  public:
    Cat() {cout << "Cat" << endl;};
};

int main()
{
  Cat c;
  return 0;
}

Когда программа запускается, она отображает

Animal
Cat

Мой вопрос теперь такой: какой конструктор на самом деле вызывается первым. Вызывается ли Cat(), а затем Cat() вызывает Animal () перед выполнением своего содержимого ИЛИ компилятор / программа смотрит на Cat(), видит, что это Animal () и сначала вызывает Animal (), а затем Cat()?

3 ответа

Конструктор Animal выполняется перед телом конструктора Cat как часть инициализации объекта Cat, когда вызывается конструктор Cat. Это так же, как если бы вы сделали это явно в списке инициализации:

Cat () : Animal() {
     cout << "Cat" << endl;
}

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

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

class Cat : public Animal
{
  public:
    Cat() 
    : Animal()
    {
        cout << "Cat" << endl;
    };
};

Затем конструктор Animal выполняется перед реализацией Cat конструктора Cat, но после его списка инициализации. Например, если у классов Cat и Animal есть несколько членов, и вы хотите инициализировать их в конструкторе, вы можете увидеть это проще:

class Animal
{
  private:
    bool haveHair;
  public:
    Animal(bool hair)
    :    haveHair(hair)
    {
        cout << "Animal" << endl;
    }
};

class Cat : public Animal
{
  public:
    Cat() 
    : Animal(true)
    {
        cout << "Cat" << endl;
    }
};

Сначала вызывается Animal(), а затем Cat().

Сначала класс Animal выделяет память, а затем Cat. Может быть, вы хотите получить доступ к ресурсам из Animal в конструкторе Cat.

Другие вопросы по тегам