Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.89/63: Рейтинг темы: голосов - 63, средняя оценка - 4.89
интересующийся
311 / 282 / 93
Регистрация: 25.09.2010
Сообщений: 1,056

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

16.03.2013, 05:43. Показов 11921. Ответов 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$
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
16.03.2013, 05:43
Ответы с готовыми решениями:

Порядок вызова конструкторов
Всем доброго дня. Наткнулся в коде на интересные грабли: test.cpp #include &quot;test.h&quot; Test test; Test::Test() {

Порядок вызова конструкторов
Есть классы First и Second. Класс Second наследуется от First. Я имею ввиду: class Second: public First { //... };

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

6
419 / 418 / 72
Регистрация: 27.05.2012
Сообщений: 1,168
16.03.2013, 09:38
происходит всё правильно - создавая объект деривед, вызывается конструктор деривед который тут же передаёт управление конструктору родительского класса, затем вызываются конструкторы полей класса деривед, а затем отрабатывает собственно конструктор деривед
1
Эксперт С++
5058 / 3118 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
21.03.2013, 07:11
xtorne21st, Кудаив всё верно сказал, я лишь добавлю, почему так происходит: поскольку класс Derived расширяет класс Base, все поля класса Base существуют и в Derived. Штука в том, что для конструирования полей объекта класса Derived, отсутствующих в Base (добавленных только в Derived), могут потребоваться поля класса Derived, унаследованные из Base. Таким образом, к началу конструирования полей класса Derived вся часть этого класса, унаследованная из Base, должна быть уже сконструирована. Для этого и вызывается конструктор класса Base, причём вызывается до того, как начнут конструироваться поля из Derived. Вообще, порядок вызова конструкторов - важная составляющая объектно-ориентированной части языка, поэтому советую вам подробно разобраться с ней.
1
интересующийся
311 / 282 / 93
Регистрация: 25.09.2010
Сообщений: 1,056
21.03.2013, 12:54  [ТС]
silent_1991, Мне иногда кажется, что они как-то вызываются рекурсивно... Ну типа вызывается объект класса Derived, соответственно вызывается конструктор Derived, но он сразу не возвращает значение (да и вообще не выполняет каких либо действий), а передает управление по иерархии классов вниз, и так происходит пока не нащупает "дно", а затем начинается возврат значений.
0
Неэпический
 Аватар для Croessmah
18149 / 10731 / 2067
Регистрация: 27.09.2012
Сообщений: 27,035
Записей в блоге: 1
21.03.2013, 13:13
При создании потомка как-то так:
Code
1
2
3
4
5
6
7
8
9
10
11
12
Конструктор потомка{
   Конструктор базового класса{
       Конструктор базового класса по нарастающей{
           "Создание" полей класса
           Код конструктора
       }
       "Создание" полей класса
       Код конструктора
   }
    "Создание" полей класса
    Код конструктора
}
Мне иногда кажется, что они как-то вызываются рекурсивно...
Причем тут рекурсия?
1
Эксперт С++
5058 / 3118 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
21.03.2013, 13:31
Цитата Сообщение от xtorne21st Посмотреть сообщение
silent_1991, Мне иногда кажется, что они как-то вызываются рекурсивно... Ну типа вызывается объект класса Derived, соответственно вызывается конструктор Derived, но он сразу не возвращает значение (да и вообще не выполняет каких либо действий), а передает управление по иерархии классов вниз, и так происходит пока не нащупает "дно", а затем начинается возврат значений.
Конструктор вообще никаких значений не возвращает. И "рекурсия" в данном случае неверный термин. А вызываются конструкторы действительно так, как вы сказали - конструктор самого нижнего в иерархии класса (иерархию принято представлять так: базовый класс вверху, производный - внизу; соответственно, то, что вы назвали "дном" - на самом деле вершина иерархии) вызывает конструктор своего родителя, тот, в свою очередь, своего родителя, и так происходит до самого верха иерархии. После отработки конструктора самого базового класса начинается работа конструктора следующего в иерархии класса, затем следующего, и в конце концов последним завершит свою работу конструктор класса, находящегося в самом низу иерархии. Это всё для одиночного наследования. Для множественного наследования всё так же, только конструктор производного класса вызывает не один, а несколько конструкторов всех базовых классов в порядке, перечисленном в списке родителей. Таким образом, здесь получается не список, а дерево вызовов с обходом в глубину.
1
интересующийся
311 / 282 / 93
Регистрация: 25.09.2010
Сообщений: 1,056
21.03.2013, 18:55  [ТС]
Спасибо за детальное разъяснение
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
21.03.2013, 18:55
Помогаю со студенческими работами здесь

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

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11680&amp;d=1772460536 Одним из. . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru