Страницы

Поиск по вопросам

пятница, 14 февраля 2020 г.

Конструкторы в C++

#cpp


Читал статью на MSDN и там был такой код:

#include   
using namespace std;

class Contained1 {
public:
    Contained1() {
        cout << "Contained1 constructor." << endl;
    }
};

class Contained2 {
public:
    Contained2() {
        cout << "Contained2 constructor." << endl;
    }
};

class Contained3 {
public:
    Contained3() {
        cout << "Contained3 constructor." << endl;
    }
};

class BaseContainer {
public:
    BaseContainer() {
        cout << "BaseContainer constructor." << endl;
    }
private:
    Contained1 c1;
    Contained2 c2;
};

class DerivedContainer : public BaseContainer {
public:
    DerivedContainer() : BaseContainer() {
        cout << "DerivedContainer constructor." << endl;
    }
private:
    Contained3 c3;
};

int main(void) 
{
    DerivedContainer dc;
}


Там было написано: Сначала вызывается конструктор базового класса, затем инициализируются
члены базового класса..., но у меня выводит: 

Contained1 constructor.
Contained2 constructor.
BaseContainer constructor.
Contained3 constructor.
DerivedContainer constructor.


Я не понимаю почему он сначала инициализирует члены базового класса, а потом выполняет
конструктор
    


Ответы

Ответ 1



При вызове конструктора сначала произойдет инициализация его членов (либо значениями, которые вы указали явно, либо значениями по умалчанию, ну или мусором), а уже потом произойдет то, что вы прописали внутри фигурных скобок в конструкторе. Тобишь: class BaseContainer { public: BaseContainer() /*вот сдесь произойдет инициализация членов*/ { /*а вот сдесь уже все что вы описали в конструкторе*/ cout << "BaseContainer constructor." << endl; } private: Contained1 c1; Contained2 c2; }; Когда вы делаете так: BaseContainer alfa; Вызывется конструктор BaseContainer по умолчанию, который сначала инициализирует члены класса, а потом уже выполнит все, что вы указали в фигурных скобках. PS важно понимать, что ИНИЦИАЛИЗАЦИЯ это не присваивание, и происходит оно прежде, чем будет выполнена какая-либо инструкция в фигурных скобках. Тобишь, если совсем по простому, между вызовом конструктора и открытием фигурной скобки.

Ответ 2



Давайте разбираться. Итак, написано - Вызывает конструкторы базовых классов и членов в порядке объявления. Т.е. у вас сначала конструируется базовый класс - BaseContainer, потом конструктор члена Contained3 (к счастью, члены у вас не являются производными, так что глубже копать не нужно). И только потом вызывается сам конструктор DerivedContainer(). И так для каждого класса. BaseContainer своего базового класса не имеет, так что в порядке объявления вызываются только конструкторы членов - Contained1 Contained2 а затем сам конструктор базового класса BaseContainer Затем, как уже мы говорили, вызовется конструктор Contained3 и последним - самый "внешний" конструктор DerivedContainer(). Итак, Contained1 Contained2 BaseContainer Contained3 DerivedContainer Все, как написано в MSDN... Мне кажется, вы неверно прочли Вызывает конструкторы базовых классов и членов в порядке объявления. как Вызывает конструкторы базовых классов и членов базового класса в порядке объявления. - т.е. что вызывается конструктор базового класса, а потом конструкторы членов базового же класса...

Ответ 3



Для любого класса порядок конструирования таков: Конструктор базового класса (если есть базовый) Конструкторы членов класса Свой конструктор Этот порядок действует и для вашего базового класса, поэтому сначала конструируются его члены, потом вызывается конструктор базового, после конструктор члена этого класса, а потом конструктор данного класса, что вы и видите в результате...

Комментариев нет:

Отправить комментарий