Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 35, средняя оценка - 4.91
xtorne21st
интересующийся
300 / 271 / 19
Регистрация: 25.09.2010
Сообщений: 1,056
#1

Порядок вызова конструкторов - C++

16.03.2013, 05:43. Просмотров 4672. Ответов 6
Метки нет (Все метки)

на срр-reference нашёл тему про виртуальный деструктор, но я так и не понял (да там и не объясняется), почему именно конструктор класса Object вызывается вторым по счёту после вызова конструктора базового класса? Ведь он же по идее находится внутри класса Derived, следовательно сначала должен вызваться конструктор Derived и после инициализации объекта своим конструктором уже создать объект класса Object и вызвать его конструктор. Но всё происходит иначе:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <iostream>
 
using namespace std;
 
class Object  
{
  public:
    Object() { cout << "Object::ctor()" << endl; }
   ~Object() { cout << "Object::dtor()" << endl; }
};
 
class Base 
{
  public:
    Base() { cout << "Base::ctor()" << endl; }
    virtual ~Base() { cout << "Base::dtor()" << endl; } 
    virtual void print() = 0;
};
 
class Derived: public Base 
{
  public:
    Derived() { cout << "Derived::ctor()" << endl; }
   ~Derived() { cout << "Derived::dtor()" << endl; }    
    void print() {}   
    Object  obj;
};
 
int main ()
{
    Base * p = new Derived;
    delete p;
    return 0;
}
Bash
1
2
3
4
5
6
7
8
ilyuha21st@coldshoot:~/Projects$ ./prog
Base::ctor()
Object::ctor()
Derived::ctor()
Derived::dtor()
Object::dtor()
Base::dtor()
ilyuha21st@coldshoot:~/Projects$
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
16.03.2013, 05:43     Порядок вызова конструкторов
Посмотрите здесь:

Наследование конструкторов? C++
C++ Классы, наследование, порядок вызова конструкторов
C++ запуск конструкторов
C++ Конфликт конструкторов.
Порядок вызова конструкторов при множественном наследовании C++
C++ Порядок вызова конструкторов/деструкторов
оформить решение в виде функции следующими способами: 1. функция расположена после ее вызова; 2. функция расположена после до ее вызова; 3. функ C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Кудаив
329 / 406 / 24
Регистрация: 27.05.2012
Сообщений: 1,165
Завершенные тесты: 2
16.03.2013, 09:38     Порядок вызова конструкторов #2
происходит всё правильно - создавая объект деривед, вызывается конструктор деривед который тут же передаёт управление конструктору родительского класса, затем вызываются конструкторы полей класса деривед, а затем отрабатывает собственно конструктор деривед
silent_1991
Эксперт С++
4952 / 3028 / 149
Регистрация: 11.11.2009
Сообщений: 7,026
Завершенные тесты: 1
21.03.2013, 07:11     Порядок вызова конструкторов #3
xtorne21st, Кудаив всё верно сказал, я лишь добавлю, почему так происходит: поскольку класс Derived расширяет класс Base, все поля класса Base существуют и в Derived. Штука в том, что для конструирования полей объекта класса Derived, отсутствующих в Base (добавленных только в Derived), могут потребоваться поля класса Derived, унаследованные из Base. Таким образом, к началу конструирования полей класса Derived вся часть этого класса, унаследованная из Base, должна быть уже сконструирована. Для этого и вызывается конструктор класса Base, причём вызывается до того, как начнут конструироваться поля из Derived. Вообще, порядок вызова конструкторов - важная составляющая объектно-ориентированной части языка, поэтому советую вам подробно разобраться с ней.
xtorne21st
интересующийся
300 / 271 / 19
Регистрация: 25.09.2010
Сообщений: 1,056
21.03.2013, 12:54  [ТС]     Порядок вызова конструкторов #4
silent_1991, Мне иногда кажется, что они как-то вызываются рекурсивно... Ну типа вызывается объект класса Derived, соответственно вызывается конструктор Derived, но он сразу не возвращает значение (да и вообще не выполняет каких либо действий), а передает управление по иерархии классов вниз, и так происходит пока не нащупает "дно", а затем начинается возврат значений.
Croessmah
Модератор
Эксперт CЭксперт С++
12703 / 7177 / 801
Регистрация: 27.09.2012
Сообщений: 17,703
Записей в блоге: 2
Завершенные тесты: 1
21.03.2013, 13:13     Порядок вызова конструкторов #5
При создании потомка как-то так:
Код
Конструктор потомка{
   Конструктор базового класса{
       Конструктор базового класса по нарастающей{
           "Создание" полей класса
           Код конструктора
       }
       "Создание" полей класса
       Код конструктора
   }
    "Создание" полей класса
    Код конструктора
}
Мне иногда кажется, что они как-то вызываются рекурсивно...
Причем тут рекурсия?
silent_1991
Эксперт С++
4952 / 3028 / 149
Регистрация: 11.11.2009
Сообщений: 7,026
Завершенные тесты: 1
21.03.2013, 13:31     Порядок вызова конструкторов #6
Цитата Сообщение от xtorne21st Посмотреть сообщение
silent_1991, Мне иногда кажется, что они как-то вызываются рекурсивно... Ну типа вызывается объект класса Derived, соответственно вызывается конструктор Derived, но он сразу не возвращает значение (да и вообще не выполняет каких либо действий), а передает управление по иерархии классов вниз, и так происходит пока не нащупает "дно", а затем начинается возврат значений.
Конструктор вообще никаких значений не возвращает. И "рекурсия" в данном случае неверный термин. А вызываются конструкторы действительно так, как вы сказали - конструктор самого нижнего в иерархии класса (иерархию принято представлять так: базовый класс вверху, производный - внизу; соответственно, то, что вы назвали "дном" - на самом деле вершина иерархии) вызывает конструктор своего родителя, тот, в свою очередь, своего родителя, и так происходит до самого верха иерархии. После отработки конструктора самого базового класса начинается работа конструктора следующего в иерархии класса, затем следующего, и в конце концов последним завершит свою работу конструктор класса, находящегося в самом низу иерархии. Это всё для одиночного наследования. Для множественного наследования всё так же, только конструктор производного класса вызывает не один, а несколько конструкторов всех базовых классов в порядке, перечисленном в списке родителей. Таким образом, здесь получается не список, а дерево вызовов с обходом в глубину.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.03.2013, 18:55     Порядок вызова конструкторов
Еще ссылки по теме:

C++ нужно чтобы функция располагалась до ее вызова, после ее вызова и в другом файле. Как это сделать?
C++ Является ли правильным проектирование классов с методами у которых есть определённый порядок вызова
Просмотреть порядок вызова функций в отладчике vs 2013 C++
Порядок вызова конструкторов при присваивании объектов одного класса C++
C++ Порядок вызова конструкторов

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
xtorne21st
интересующийся
300 / 271 / 19
Регистрация: 25.09.2010
Сообщений: 1,056
21.03.2013, 18:55  [ТС]     Порядок вызова конструкторов #7
Спасибо за детальное разъяснение
Yandex
Объявления
21.03.2013, 18:55     Порядок вызова конструкторов
Ответ Создать тему
Опции темы

Текущее время: 12:05. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru