Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.57/7: Рейтинг темы: голосов - 7, средняя оценка - 4.57
23 / 23 / 3
Регистрация: 15.12.2012
Сообщений: 314
1

Foo::foo(): x(dx), y(dy) {}; Зачем

02.02.2013, 18:15. Показов 1457. Ответов 15
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Очень часто видел конструктор типа
C++
1
Foo::foo(): x(dx), y(dy) {};
Сам использовал только в инициализации структур. Какие отличия от стандартного
C++
1
2
3
4
5
Foo:foo(int dx, int dy)
{
    x = dx;
    y = dy;
}
Что предпочтительнее, какие преимущества у конструкции первого типа?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
02.02.2013, 18:15
Ответы с готовыми решениями:

Int& foo() и int foo()
При передаче переменной по ссылке все понятно. Но я не пойму логики возвращения по ссылке....

Какое число вернет foo(5)?
int foo (int n) { if (n <= 0) return 0; return foo (n - 2) + foo (n / 2) + 1; }...

Задачка: какое значение вернет foo(7)?
Как решаются такие рода задачки, подскажите пожалуйста. int foo(int n) { if(n<=0) ...

Обеспечить вызов функции foo в x% случаев
Добрый день! Возникла следующая трудность. Есть функции void increment() и void...

15
Эксперт С++
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, вызываются сразу конструкторы членов с параметрами. Во втором сначала контрукторы членов без параметров. Потом присваиваивание в теле конструктора класса.
Цитата Сообщение от vbloodv Посмотреть сообщение
Что предпочтительнее, какие преимущества у конструкции первого типа?
Думаю, сам поймешь.
1
23 / 23 / 3
Регистрация: 15.12.2012
Сообщений: 314
02.02.2013, 18:24  [ТС] 4
Цитата Сообщение от Nick Alte Посмотреть сообщение
Что ещё более важно, если член не имеет конструктора по умолчанию, то единственный способ его инициализировать - список инициализации.
Немножко не понимаю это момент, если член не имеет конструктора и единственный способ его проинициализировать это через список, т.е для доступа к констуктару нет возможности(к примеру такой член находится в статической библиотеке), но тогда как узнать какие поля класса можно инициализировать через список инициализации ?

Добавлено через 17 секунд
Цитата Сообщение от Vourhey Посмотреть сообщение
Думаю, сам поймешь.
Уже понял
0
Эксперт С++
1674 / 1046 / 174
Регистрация: 27.09.2009
Сообщений: 1,945
02.02.2013, 18:28 5
Цитата Сообщение от vbloodv Посмотреть сообщение
если член не имеет конструктора
То его в принципе невозможно создать.
Член не может находиться в статической библиотеке, он находится в классе - то есть, в составе объектов этого класса. Если конструктор находится в статической библиотеке, то это вовсе не значит, что к нему нет доступа. Он описан в заголовочном файле, компилятор знает, как его вызывать - этого достаточно.

Цитата Сообщение от vbloodv Посмотреть сообщение
как узнать какие поля класса можно инициализировать через список инициализации
Очень просто - можно инициализировать все. Не включать в список можно только те, которые могут конструироваться по умолчанию, если нужно, чтобы именно по умолчанию они инициализировались.
1
23 / 23 / 3
Регистрация: 15.12.2012
Сообщений: 314
02.02.2013, 18:34  [ТС] 6
Цитата Сообщение от Nick Alte Посмотреть сообщение
Очень просто - можно инициализировать все.
C++
1
2
3
4
5
6
7
8
class Foo // псевдокод
{
int id;
string name;
int range;
int ability;
float rating;
}
Как будет происходить инициализация такого класса? Если значение переменной id нужно проинициализировать по умолчанию?
0
Каратель
Эксперт С++
6609 / 4028 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
02.02.2013, 18:52 7
Цитата Сообщение от vbloodv Посмотреть сообщение
Как будет происходить инициализация такого класса? Если значение переменной id нужно проинициализировать по умолчанию?
id иницализируется мусором
для name - вызван конструктор без параметров
в остальных полях - мусор

порядок инициализации соотвествует порядку объявления переменных в классе
если написать так
C++
1
2
3
Foo::Foo() : id()
{
}
то в id будет 0, для name вызовется конструктор без параметров, в оставшихся полях - мусор.
1
Эксперт С++
1674 / 1046 / 174
Регистрация: 27.09.2009
Сообщений: 1,945
02.02.2013, 18:53 8
По умолчанию встроенные числовые типы имеют неопределённое значение. Под "неопределённым значением" в данном контексте понимается, что там может оказаться какое угодно число, как повезёт. Так что при конструировании Foo по умолчанию вся процедура сведётся к вызову конструктора по умолчанию для string. Если надо, чтобы при конструировании Foo по умолчанию член id принимал определённое значение, пишем соответствующий конструктор с сигнатурой Foo::Foo() и упоминаем id в списке инициализации.
1
Форумчанин
Эксперт CЭксперт С++
8215 / 5045 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
02.02.2013, 19:38 9
При использовании списка инициализации для членов вызывается конструктор копирования, объекты конструируются заранее со значениями, переданными им. Если этого не происходит, то сначала вызывается конструктор по-умолчанию, а далее вызывается оператор присвоений. Не говоря о том, что это логически не совсем то, чего мы хотели, это еще и лишние операции. Вдобавок, ссылки и константные члены обязаны быть проинициализированны на момент объявления.
За сим список инициализации стоит использовать всегда, за одним редким исключением, когда требуется множественное присваивание.
1
Higher
1953 / 1219 / 120
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
02.02.2013, 19:50 10
Вот только работает список инициализации не всегда так, как это кажется на первый взгляд.
А это может привести к очень трудноуловимым ошибкам.
Ну и еще у него некошерный синтаксис.
Что касается начальной инициализации - компайлер это должен соптимизировать(но проверять лень).
Так что я все-таки предпочитаю обычную инициализацию, а после двоеточия пишу лишь вызов конструкторов.

Добавлено через 3 минуты
Цитата Сообщение от diagon Посмотреть сообщение
Вот только работает список инициализации не всегда так, как это кажется на первый взгляд.
А это может привести к очень трудноуловимым ошибкам.
Кривой, но пример.
0
Jupiter
02.02.2013, 20:03
  #11

Не по теме:

Цитата Сообщение от diagon Посмотреть сообщение
Кривой, но пример.
это уже слишком...

0
DU
1500 / 1146 / 165
Регистрация: 05.12.2011
Сообщений: 2,279
02.02.2013, 20:08 12
работает так, как и должен работать. то, что при инициализации вызывается метод, который обращается к еще неинициализированному мемберу - это не вина списка инициализации, что в этой ссылке и написано. так можно и без всяких потоков написать.
0
Higher
1953 / 1219 / 120
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
02.02.2013, 20:33 13
Цитата Сообщение от DU Посмотреть сообщение
так можно и без всяких потоков написать.
Ну, тогда оно просто не будет работать. В случае с потоками оно всего лишь иногда не работает, что еще веселее.

Цитата Сообщение от DU Посмотреть сообщение
это не вина списка инициализации
Вина списка инициализации в том, что он инициализирует мемберы не в том порядке, в котором они перечислены в списке.
В целях рефакторинга поменял переменные местами - программа перестала работать. Нет уж, пусть такая ситуация остается в анекдотах.
Хотя, соглашусь, это некритично. Для меня наиболее важно то, что
Цитата Сообщение от diagon Посмотреть сообщение
у него некошерный синтаксис
0
Каратель
Эксперт С++
6609 / 4028 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
02.02.2013, 20:47 14
Цитата Сообщение от diagon Посмотреть сообщение
Вина списка инициализации в том, что он инициализирует мемберы не в том порядке, в котором они перечислены в списке.
вот как раз тут все логично, это вина программиста, который не знает язык или пишет код в не в здравом уме
0
Форумчанин
Эксперт CЭксперт С++
8215 / 5045 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
02.02.2013, 23:52 15
Цитата Сообщение от diagon Посмотреть сообщение
компайлер это должен соптимизировать(но проверять лень).
думаю это справедливо лишь для POD типов

Список инициализации не виноват в проблемах навроде того, что перечисляют не в том порядке, в каком объявляют в классе, или, если рассматривать проблему в общем случае, используют обращение к неинициализированным переменным.
0
silent_1991
04.02.2013, 11:07     Foo::foo(): x(dx), y(dy) {}; Зачем
  #16

Не по теме:

Цитата Сообщение от diagon Посмотреть сообщение
Ну и еще у него некошерный синтаксис.
Хм, а мне наоборот нравится...

0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
04.02.2013, 11:07

Отметьте все верные утверждения относительно вызова функции foo
Есть три версии функции foo: void foo(char) { std::cout << "char" << std::endl; } void...

Где может быть использована сигнатура int& foo()=7
Друзья, это чисто теоретический вопрос. Подскажите где может быть использована такая функция....

int const * const foo(const int* param) const - разъясните значение квалификаторов
int const * const foo(const int* param) const -----1------2----------3----------------4 1: ?...

Копировать значение поля m_moo в значение поля m_moo класса foo
А что означает запись? Foo1(Foo1 const& foo):m_moo(foo.moo) то что это к.копирования понятно.Не...


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

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru