2013-08-28 2 views
0

Я посмотрел на подобные запросы, но, похоже, я теряюсь. У меня есть простой пример, поэтому, пожалуйста, учтите следующее: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() ?

+1

Возможно, последнее, но почему это имеет значение? – PherricOxide

+0

Скорее всего, что Cat вызывается первым, а затем запускает конструктор Animal перед печатью «Cat». Но если вы действительно хотите проверить это, настройте статическую переменную и распечатайте, а затем увеличьте ее, чтобы увидеть, какой из них выполняется первым. – Radnyx

+1

Вызывается 'Cat()', во-первых, он вызывает все базовые конструкторы в соответствующем порядке, затем 'vptr', если нужно (я думаю), и список инициализаторов, а затем его собственное тело. – lapk

ответ

3

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

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

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

+0

+1 Хорошее правило: 'Это то же самое, что если бы вы сделали это явно в списке инициализации' – Wolf

0

Первое животное(), а затем вызывается Cat().

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

+0

' Сначала класс Animal выделяет память', вы здесь не говорите о C++. – Wolf

1

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

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

Затем конструктор животных выполняется до реализации 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; 
    } 
}; 

 Смежные вопросы

  • Нет связанных вопросов^_^