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

Порядок инициализации полей в конструкторе - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 21, средняя оценка - 4.76
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16843 / 5264 / 323
Регистрация: 30.03.2009
Сообщений: 14,159
Записей в блоге: 26
05.08.2010, 21:30     Порядок инициализации полей в конструкторе #1
Имеется некий класс T. В нём имеются поля m_F1 (указатель) и m_F2 (неважно). Конструктор выглядит так:

C++
1
2
3
T::T()
  : m_F1 (new ...),
    m_F2 (m_F1->...)
В момент инициализации поля m_F2 оказывается, что m_F1 неинициализировано. Я правильно понимаю, что при такой инициализации стандарт не гарантирует порядок инициализации полей? Или я что-то не так делаю?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
05.08.2010, 21:30     Порядок инициализации полей в конструкторе
Посмотрите здесь:

Определить конструктор для инициализации полей по умолчанию C++
Порядок инициализации предков C++
исключения в конструкторе C++
Шаблон в конструкторе C++
Порядок переменных в списке инициализации C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
CheshireCat
Эксперт С++
2907 / 1235 / 78
Регистрация: 27.05.2008
Сообщений: 3,309
05.08.2010, 21:55     Порядок инициализации полей в конструкторе #2
Нет, неправильно. Стандарт гарантирует, что поля (члены) класса инициализируются строго в порядке их объявления в классе, и никак иначе, независимо от порядка их перечисления в списке инициализации.
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16843 / 5264 / 323
Регистрация: 30.03.2009
Сообщений: 14,159
Записей в блоге: 26
05.08.2010, 22:11  [ТС]     Порядок инициализации полей в конструкторе #3
ОО!! понял. Спасибо

Добавлено через 1 минуту
А есть идеи, почему порядок привязан к описанию в классе, а не к порядку описания в инициализации?
CyBOSSeR
Эксперт C++
 Аватар для CyBOSSeR
2294 / 1664 / 86
Регистрация: 06.03.2009
Сообщений: 3,675
05.08.2010, 22:27     Порядок инициализации полей в конструкторе #4
Думаю, здесь две причины:
1. Поля лежат в памяти в порядке объявления и в нем же должны инициализироватся.
2. Списоков инициализации может быть много, а объявление только одно.
Возможно есть и более веские причины.
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16843 / 5264 / 323
Регистрация: 30.03.2009
Сообщений: 14,159
Записей в блоге: 26
05.08.2010, 22:40  [ТС]     Порядок инициализации полей в конструкторе #5
Цитата Сообщение от CyBOSSeR Посмотреть сообщение
1. Поля лежат в памяти в порядке объявления и в нем же должны инициализироватся.
2. Списоков инициализации может быть много, а объявление только одно
Если честно, то ни в том, ни в другом не вижу логики. Если инициализацию написать внутри фигурных скобок в виде операций присваивания, то там порядок будет тот, какой нужно. Во всяком случае там, где одно поле зависит от другого. Не вижу объективных причин, почему не делать так же и при инициализации после двоеточия (вне фигурных скобок)
CyBOSSeR
Эксперт C++
 Аватар для CyBOSSeR
2294 / 1664 / 86
Регистрация: 06.03.2009
Сообщений: 3,675
05.08.2010, 22:44     Порядок инициализации полей в конструкторе #6
Evg, дело в другом. Когда ты присваиваешь значения полям внутри конструктора, а не в списке инициализации - это именно присваивание, а не инициализация. Инициализация полей к этому времени уже закончена: все неинициализированные в списке инициализации поля встроенного типа остались неинициализорованными, для полей же пользовательских типов были вызваны конструкторы по умолчанию.
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16843 / 5264 / 323
Регистрация: 30.03.2009
Сообщений: 14,159
Записей в блоге: 26
05.08.2010, 22:52  [ТС]     Порядок инициализации полей в конструкторе #7
При таком раскладе более-менее понятно. Но всё равно как-то неудобно. Очередное место в Си++, где чтобы понять, что делается в одном месте, надо сначала посмотреть в другое место. С таким подходом радостью бы плюнул на инициализацию через двоеточие, но поле const
CyBOSSeR
Эксперт C++
 Аватар для CyBOSSeR
2294 / 1664 / 86
Регистрация: 06.03.2009
Сообщений: 3,675
05.08.2010, 23:08     Порядок инициализации полей в конструкторе #8
Evg, почему же, все логично. Просто не нужно полагаться на какой либо порядок в списке инициализации.
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16843 / 5264 / 323
Регистрация: 30.03.2009
Сообщений: 14,159
Записей в блоге: 26
05.08.2010, 23:37  [ТС]     Порядок инициализации полей в конструкторе #9
Цитата Сообщение от CyBOSSeR Посмотреть сообщение
Просто не нужно полагаться на какой либо порядок в списке инициализации
Ситуация такая. Оба поля имеют модификатор const, а потому их можно инициализировать только через двоеточие - нормальное явление. Инициализация полей зависит друг от друга - тоже нормальное явление. Если бы в поле с модификатором const разрешалось писать внутри конструктора - всё было бы нормально (на мой взгляд такое поведение разумно, но может в идеологию не укладывается). Но писать нельзя, а потому приходится извращаться. Я понимаю, что в Си и того нет, но всё-равно как-то через ж...у получается.
CyBOSSeR
Эксперт C++
 Аватар для CyBOSSeR
2294 / 1664 / 86
Регистрация: 06.03.2009
Сообщений: 3,675
05.08.2010, 23:57     Порядок инициализации полей в конструкторе #10
Evg, если можно - покажи отрывок кода с инициализацией, возможно что-нибудь получится придумать.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
06.08.2010, 00:06     Порядок инициализации полей в конструкторе
Еще ссылки по теме:

C++ Что такое порядок инициализации таблицы виртуальных методов?
C++ О конструкторе копирования
Порядок инициализации членов класса C++

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

Или воспользуйтесь поиском по форуму:
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16843 / 5264 / 323
Регистрация: 30.03.2009
Сообщений: 14,159
Записей в блоге: 26
06.08.2010, 00:06  [ТС]     Порядок инициализации полей в конструкторе #11
Да я через порядок полей в классе проблему решил. Я просто высказываю очередное недовольство языком Си++

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class TContext { ... };
class TTable { ... };
 
class T3
{
  ...
  TContext * const m_Context;
  TTable * const m_Table1;
  TTable * const m_Table2;
  ...
};
 
T3::T3 (int param)
  : m_Context (new TContext (param)),
    m_Table1 (m_Context->CreateTable (1)),
    m_Table2 (m_Context->CreateTable (2))
{
  ...
}
Yandex
Объявления
06.08.2010, 00:06     Порядок инициализации полей в конструкторе
Ответ Создать тему
Опции темы

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