Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Корректная инициалицация членов класса.

590
27 января 2009 года
Gigahard
223 / / 03.04.2006
Недавно почитывая книженцию по C++ прочитал про одну вещь, которая оказалась для меня в новинку. А именно про особенность инициализации членов класса.
Допустим есть у нас вот такой класс:
 
Код:
class Abracadabra
{
     public:
     Abracadabra();
     ~Abracadabra(){}

     //Содержит в себе другие пользовательские классы MyDog, MyBook.
     MyDog mDog;
     MyBook mBook;
};


Допустим классы MyDog и MyBook могут инициализироваться числом определяющих к примеру возраст и строкой определяющей название: MyDod(3), MyBook("FooBar").
Особенностью класса Abracadabra допустим является то, что члены класса (объекты mDog и mBook) НЕ создаются со значениями по умолчанию, а инициализируются классом Abracadabra.
Т.е. к примеру, конструктор класса Abracadabra имеет такой вид:
 
Код:
Abracadabra::Abracadabra(): mDog(3), mCat("FooBar"){}


Собственно здесь я ничего нового не изложил. Но вот о чем прочел в книжке...


Раньше я думал, что порядок инициализаторов ...abra(): mDog(3), mBook("FooBar"){} Может иметь произвольный порядок, т.к. по сути мы до запуска конструктора основного класса запускаем конструкторы его членов. По идее, как мне казалось, порядок здесь не важен.
Однако в книге акцентирован тот момент, что инициализаторы обязательно должны идти в том же порядке, что и в объявлении членов класса!
Т.е. по всей видимости запись
 
Код:
Abracadabra::Abracadabra(): mBook("FooBar"), mDog(3){}

будет уже не корректной.

Терзают меня смутные сомнения, а так ли это? Или это необоснованные страшилки?
341
27 января 2009 года
Der Meister
874 / / 21.12.2007
[QUOTE=Gigahard]Однако в книге акцентирован тот момент, что инициализаторы обязательно должны идти в том же порядке, что и в объявлении членов класса![/QUOTE]Фигня какая-то... Мне не интересны стандарты, но даже несмотря на потенциальную свою неосведомлённость в этой связи, осмелюсь заявить, что ситуация автором произведения явно искажена. Момент тут если и будет, то другого плана: порядок следования инициализаторов не важен, а реально поля будут инициализированы/сконструированы в порядке их (а не инициализаторов) следования при объявлении.
590
27 января 2009 года
Gigahard
223 / / 03.04.2006
Да похоже это я ступил... Бегло прочел... Сейчас еще разок перечитал. Речь там идет о порядке инициализации членов класса. Просто там выделен момент, когда допустим один член класса инициализируется значением другого ранее инициализированного члена. Т.е. если в этом случае перепутать порядок инициализаторов, то может в итоге произойти некорректная инициализация.
Осознал.
К примеру:
 
Код:
class FooBar
{
     public:
     FooBar();
     ~FooBar(){}
     int a;
     int b;
};

Если мы запишем конструктор в виде:
 
Код:
FooBar::FooBar():b(256), a(b){}

То в итоге получим не тот результат который ожидали. Т.е. первым все равно будет инициализироватся a и ему будет присвоено значение еще не инициализированного члена b. А член b инициализируется уже потом. В результате мы получим мусор в a и инициализированный b.

Я сначала не врубился в смысл строк, т.к. порядок инициализации до этого для меня был самоочевиден и я как то даже не задумывался над возможной проблемой.
87
27 января 2009 года
Kogrom
2.7K / / 02.02.2008
Цитата: Der Meister
Мне не интересны стандарты


А почему? Удобно же цитаты приводить.

[QUOTE=Стандарт_п12.6.2(5)]— Then, nonstatic data members shall be initialized in the order they were declared in the class definition
(again regardless of the order of the mem-initializers).[/QUOTE]
Мой вольный перевод (английский у меня не очень, извиняйте) : После этого должны быть инициализированы нестатические члены-данные в порядке их определения в классе (не обращая внимания на порядок инициализвторов).

535
27 января 2009 года
Нездешний
537 / / 17.01.2008
Цитата: Gigahard
Терзают меня смутные сомнения, а так ли это? Или это необоснованные страшилки?

Недавно столкнулся с этим. Но на практике. MinGW на код вида:

 
Код:
class Test
{
    int value;
    char symbol;
public:
    Test(): symbol('k'), value(12) {}
};

ругается так: warning 'Test::symbol' will be initialized after 'int Test::value' when initialized here (на строке с конструктором)
При обратном порядке инициализаторов все тихо.
Тоже было сюрпризом :)
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог