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

147
06 декабря 2018, 21:20

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

#include <iostream>  
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.

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

Answer 1

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

class BaseContainer {
public:
    BaseContainer() /*вот сдесь произойдет инициализация членов*/ {
        /*а вот сдесь уже все что вы описали в конструкторе*/
        cout << "BaseContainer constructor." << endl;
    }
private:
    Contained1 c1;
    Contained2 c2;
};

Когда вы делаете так:

BaseContainer alfa;

Вызывется конструктор BaseContainer по умолчанию, который сначала инициализирует члены класса, а потом уже выполнит все, что вы указали в фигурных скобках.

PS важно понимать, что ИНИЦИАЛИЗАЦИЯ это не присваивание, и происходит оно прежде, чем будет выполнена какая-либо инструкция в фигурных скобках. Тобишь, если совсем по простому, между вызовом конструктора и открытием фигурной скобки.

Answer 2

Давайте разбираться. Итак, написано -

Вызывает конструкторы базовых классов и членов в порядке объявления.

Т.е. у вас сначала конструируется базовый класс - BaseContainer, потом конструктор члена Contained3 (к счастью, члены у вас не являются производными, так что глубже копать не нужно). И только потом вызывается сам конструктор DerivedContainer(). И так для каждого класса.

BaseContainer своего базового класса не имеет, так что в порядке объявления вызываются только конструкторы членов -

Contained1
Contained2

а затем сам конструктор базового класса

BaseContainer

Затем, как уже мы говорили, вызовется конструктор

Contained3 

и последним - самый "внешний" конструктор DerivedContainer().

Итак,

Contained1
Contained2
BaseContainer
Contained3 
DerivedContainer

Все, как написано в MSDN...

Мне кажется, вы неверно прочли

Вызывает конструкторы базовых классов и членов в порядке объявления.

как

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

Answer 3

Для любого класса порядок конструирования таков:

  1. Конструктор базового класса (если есть базовый)
  2. Конструкторы членов класса
  3. Свой конструктор

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

READ ALSO
Коментарии в GSON

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

В Gson имеется такая возможность как полный контроль над этапом Serializer и Deserializer объекта

136
Android MediaPlayer по URL

Android MediaPlayer по URL

На сервере лежат довольно большие файлы в формате mp3, есть необходимость прослушать их не с начала, а с определенного местаПри вызове seekTo()...

175
Создание конструктора

Создание конструктора

В домашнем задании нужно создать новый конструкторВ проекте уже существует один, который генерирует кошек

181
Отключение разделителя в SplitPane (JavaFX)

Отключение разделителя в SplitPane (JavaFX)

По ходу создания программы в JavaFX для красоты решил запретить изменять расположение разделителя (Divider)Вот моя попытка:

134