Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 35, средняя оценка - 4.91
xtorne21st
интересующийся
304 / 275 / 93
Регистрация: 25.09.2010
Сообщений: 1,056
#1

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

16.03.2013, 05:43. Просмотров 5882. Ответов 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$

http://www.cyberforum.ru/cpp-beginners/thread1857648.html
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
16.03.2013, 05:43
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Порядок вызова конструкторов (C++):

Порядок вызова конструкторов
Всем доброго дня. Наткнулся в коде на интересные грабли: test.cpp #include...

Порядок вызова конструкторов/деструкторов
Вопрос чисто теоретический. Попробую сформулировать, не ругайте если получится...

Классы, наследование, порядок вызова конструкторов
допустим у меня эсть два класса class a { publc: char *n; a() { n= new...

Порядок вызова конструкторов при множественном наследовании
Здравствуйте, меня интересует вопрос, как изменить последовательность вызова...

Порядок вызова конструкторов при присваивании объектов одного класса
Имеется код ниже. Wein dres = rom; Где dres и rom объекты класса...

6
Кудаив
409 / 408 / 72
Регистрация: 27.05.2012
Сообщений: 1,168
Завершенные тесты: 2
16.03.2013, 09:38 #2
происходит всё правильно - создавая объект деривед, вызывается конструктор деривед который тут же передаёт управление конструктору родительского класса, затем вызываются конструкторы полей класса деривед, а затем отрабатывает собственно конструктор деривед
1
silent_1991
Эксперт С++
5007 / 3065 / 270
Регистрация: 11.11.2009
Сообщений: 7,043
Завершенные тесты: 1
21.03.2013, 07:11 #3
xtorne21st, Кудаив всё верно сказал, я лишь добавлю, почему так происходит: поскольку класс Derived расширяет класс Base, все поля класса Base существуют и в Derived. Штука в том, что для конструирования полей объекта класса Derived, отсутствующих в Base (добавленных только в Derived), могут потребоваться поля класса Derived, унаследованные из Base. Таким образом, к началу конструирования полей класса Derived вся часть этого класса, унаследованная из Base, должна быть уже сконструирована. Для этого и вызывается конструктор класса Base, причём вызывается до того, как начнут конструироваться поля из Derived. Вообще, порядок вызова конструкторов - важная составляющая объектно-ориентированной части языка, поэтому советую вам подробно разобраться с ней.
1
xtorne21st
интересующийся
304 / 275 / 93
Регистрация: 25.09.2010
Сообщений: 1,056
21.03.2013, 12:54  [ТС] #4
silent_1991, Мне иногда кажется, что они как-то вызываются рекурсивно... Ну типа вызывается объект класса Derived, соответственно вызывается конструктор Derived, но он сразу не возвращает значение (да и вообще не выполняет каких либо действий), а передает управление по иерархии классов вниз, и так происходит пока не нащупает "дно", а затем начинается возврат значений.
0
Croessmah
++Ͻ
14148 / 8073 / 1512
Регистрация: 27.09.2012
Сообщений: 19,910
Записей в блоге: 3
Завершенные тесты: 1
21.03.2013, 13:13 #5
При создании потомка как-то так:
Код
Конструктор потомка{
   Конструктор базового класса{
       Конструктор базового класса по нарастающей{
           "Создание" полей класса
           Код конструктора
       }
       "Создание" полей класса
       Код конструктора
   }
    "Создание" полей класса
    Код конструктора
}
Мне иногда кажется, что они как-то вызываются рекурсивно...
Причем тут рекурсия?
1
silent_1991
Эксперт С++
5007 / 3065 / 270
Регистрация: 11.11.2009
Сообщений: 7,043
Завершенные тесты: 1
21.03.2013, 13:31 #6
Цитата Сообщение от xtorne21st Посмотреть сообщение
silent_1991, Мне иногда кажется, что они как-то вызываются рекурсивно... Ну типа вызывается объект класса Derived, соответственно вызывается конструктор Derived, но он сразу не возвращает значение (да и вообще не выполняет каких либо действий), а передает управление по иерархии классов вниз, и так происходит пока не нащупает "дно", а затем начинается возврат значений.
Конструктор вообще никаких значений не возвращает. И "рекурсия" в данном случае неверный термин. А вызываются конструкторы действительно так, как вы сказали - конструктор самого нижнего в иерархии класса (иерархию принято представлять так: базовый класс вверху, производный - внизу; соответственно, то, что вы назвали "дном" - на самом деле вершина иерархии) вызывает конструктор своего родителя, тот, в свою очередь, своего родителя, и так происходит до самого верха иерархии. После отработки конструктора самого базового класса начинается работа конструктора следующего в иерархии класса, затем следующего, и в конце концов последним завершит свою работу конструктор класса, находящегося в самом низу иерархии. Это всё для одиночного наследования. Для множественного наследования всё так же, только конструктор производного класса вызывает не один, а несколько конструкторов всех базовых классов в порядке, перечисленном в списке родителей. Таким образом, здесь получается не список, а дерево вызовов с обходом в глубину.
1
xtorne21st
интересующийся
304 / 275 / 93
Регистрация: 25.09.2010
Сообщений: 1,056
21.03.2013, 18:55  [ТС] #7
Спасибо за детальное разъяснение
0
21.03.2013, 18:55
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.03.2013, 18:55
Привет! Вот еще темы с решениями:

Странный порядок вызова конструкторов и передача временного обьекта в функцию в качестве неконстантной ссылки
Есть код //g++ 5.4.0 #include &lt;iostream&gt; struct foo { ...

Очерёдность вызова конструкторов класса
У меня есть 2 класса, к примеру Base и Mod. Mod является наследником Base....

Просмотреть порядок вызова функций в отладчике vs 2013
Собственно, вопрос - как? У меня есть проект на си, с огромным количеством...

Является ли правильным проектирование классов с методами у которых есть определённый порядок вызова
Всем привет. Вопрос к опытным программистам: Является ли в С++ практике...


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

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru