23 / 23 / 3
Регистрация: 15.12.2012
Сообщений: 314
|
|||||||||||
1 | |||||||||||
Foo::foo(): x(dx), y(dy) {}; Зачем02.02.2013, 18:15. Показов 1457. Ответов 15
Метки нет (Все метки)
Очень часто видел конструктор типа
0
|
02.02.2013, 18:15 | |
Ответы с готовыми решениями:
15
Int& foo() и int foo() Какое число вернет foo(5)? Задачка: какое значение вернет foo(7)? Обеспечить вызов функции foo в x% случаев |
1674 / 1046 / 174
Регистрация: 27.09.2009
Сообщений: 1,945
|
|
02.02.2013, 18:19 | 2 |
Стандартное - первое (называется списком инициализации). Преимущества в том, что члены, перечисленные в списке инициализации, именно инициализируются указанными значениями. Во втором случае они сначала инициализируются по умолчанию, а потом им уже в теле присваивается новое значение. Для численных типов разница незначительна, а вот для сложных объектов это может уже сказаться основательно. Что ещё более важно, если член не имеет конструктора по умолчанию, то единственный способ его инициализировать - список инициализации. Это относится и к членам, имеющим тип "ссылка".
2
|
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
|
|
02.02.2013, 18:21 | 3 |
vbloodv, вызываются сразу конструкторы членов с параметрами. Во втором сначала контрукторы членов без параметров. Потом присваиваивание в теле конструктора класса.
Думаю, сам поймешь.
1
|
23 / 23 / 3
Регистрация: 15.12.2012
Сообщений: 314
|
|
02.02.2013, 18:24 [ТС] | 4 |
Немножко не понимаю это момент, если член не имеет конструктора и единственный способ его проинициализировать это через список, т.е для доступа к констуктару нет возможности(к примеру такой член находится в статической библиотеке), но тогда как узнать какие поля класса можно инициализировать через список инициализации ?
Добавлено через 17 секунд Уже понял
0
|
1674 / 1046 / 174
Регистрация: 27.09.2009
Сообщений: 1,945
|
|
02.02.2013, 18:28 | 5 |
То его в принципе невозможно создать.
Член не может находиться в статической библиотеке, он находится в классе - то есть, в составе объектов этого класса. Если конструктор находится в статической библиотеке, то это вовсе не значит, что к нему нет доступа. Он описан в заголовочном файле, компилятор знает, как его вызывать - этого достаточно. Очень просто - можно инициализировать все. Не включать в список можно только те, которые могут конструироваться по умолчанию, если нужно, чтобы именно по умолчанию они инициализировались.
1
|
23 / 23 / 3
Регистрация: 15.12.2012
Сообщений: 314
|
||||||
02.02.2013, 18:34 [ТС] | 6 | |||||
0
|
Каратель
|
||||||
02.02.2013, 18:52 | 7 | |||||
id иницализируется мусором
для name - вызван конструктор без параметров в остальных полях - мусор порядок инициализации соотвествует порядку объявления переменных в классе если написать так
1
|
1674 / 1046 / 174
Регистрация: 27.09.2009
Сообщений: 1,945
|
|
02.02.2013, 18:53 | 8 |
По умолчанию встроенные числовые типы имеют неопределённое значение. Под "неопределённым значением" в данном контексте понимается, что там может оказаться какое угодно число, как повезёт. Так что при конструировании Foo по умолчанию вся процедура сведётся к вызову конструктора по умолчанию для string. Если надо, чтобы при конструировании Foo по умолчанию член id принимал определённое значение, пишем соответствующий конструктор с сигнатурой Foo::Foo() и упоминаем id в списке инициализации.
1
|
Форумчанин
8215 / 5045 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
|
|
02.02.2013, 19:38 | 9 |
При использовании списка инициализации для членов вызывается конструктор копирования, объекты конструируются заранее со значениями, переданными им. Если этого не происходит, то сначала вызывается конструктор по-умолчанию, а далее вызывается оператор присвоений. Не говоря о том, что это логически не совсем то, чего мы хотели, это еще и лишние операции. Вдобавок, ссылки и константные члены обязаны быть проинициализированны на момент объявления.
За сим список инициализации стоит использовать всегда, за одним редким исключением, когда требуется множественное присваивание.
1
|
Higher
|
|
02.02.2013, 19:50 | 10 |
Вот только работает список инициализации не всегда так, как это кажется на первый взгляд.
А это может привести к очень трудноуловимым ошибкам. Ну и еще у него некошерный синтаксис. Что касается начальной инициализации - компайлер это должен соптимизировать(но проверять лень). Так что я все-таки предпочитаю обычную инициализацию, а после двоеточия пишу лишь вызов конструкторов. Добавлено через 3 минуты Кривой, но пример.
0
|
Jupiter
|
02.02.2013, 20:03
#11
|
0
|
1500 / 1146 / 165
Регистрация: 05.12.2011
Сообщений: 2,279
|
|
02.02.2013, 20:08 | 12 |
работает так, как и должен работать. то, что при инициализации вызывается метод, который обращается к еще неинициализированному мемберу - это не вина списка инициализации, что в этой ссылке и написано. так можно и без всяких потоков написать.
0
|
Higher
|
|
02.02.2013, 20:33 | 13 |
Ну, тогда оно просто не будет работать. В случае с потоками оно всего лишь иногда не работает, что еще веселее.
Вина списка инициализации в том, что он инициализирует мемберы не в том порядке, в котором они перечислены в списке. В целях рефакторинга поменял переменные местами - программа перестала работать. Нет уж, пусть такая ситуация остается в анекдотах. Хотя, соглашусь, это некритично. Для меня наиболее важно то, что
0
|
Форумчанин
8215 / 5045 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
|
|
02.02.2013, 23:52 | 15 |
думаю это справедливо лишь для POD типов
Список инициализации не виноват в проблемах навроде того, что перечисляют не в том порядке, в каком объявляют в классе, или, если рассматривать проблему в общем случае, используют обращение к неинициализированным переменным.
0
|
silent_1991
|
04.02.2013, 11:07
Foo::foo(): x(dx), y(dy) {}; Зачем
#16
|
0
|
04.02.2013, 11:07 | |
Отметьте все верные утверждения относительно вызова функции foo Где может быть использована сигнатура int& foo()=7 int const * const foo(const int* param) const - разъясните значение квалификаторов Копировать значение поля m_moo в значение поля m_moo класса foo Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |