С Новым годом! Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
vbloodv
22 / 22 / 0
Регистрация: 15.12.2012
Сообщений: 314
#1

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

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

Очень часто видел конструктор типа
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
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
02.02.2013, 18:15
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Foo::foo(): x(dx), y(dy) {}; Зачем (C++):

Какое число вернет foo(5)? - C++
int foo (int n) { if (n <= 0) return 0; return foo (n - 2) + foo (n / 2) + 1; } Вставляю код, выполняю с нужным...

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

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

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

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

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

15
Nick Alte
Эксперт С++
1642 / 1014 / 119
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
02.02.2013, 18:19 #2
Стандартное - первое (называется списком инициализации). Преимущества в том, что члены, перечисленные в списке инициализации, именно инициализируются указанными значениями. Во втором случае они сначала инициализируются по умолчанию, а потом им уже в теле присваивается новое значение. Для численных типов разница незначительна, а вот для сложных объектов это может уже сказаться основательно. Что ещё более важно, если член не имеет конструктора по умолчанию, то единственный способ его инициализировать - список инициализации. Это относится и к членам, имеющим тип "ссылка".
2
Vourhey
Почетный модератор
6486 / 2260 / 123
Регистрация: 29.07.2006
Сообщений: 12,536
02.02.2013, 18:21 #3
vbloodv, вызываются сразу конструкторы членов с параметрами. Во втором сначала контрукторы членов без параметров. Потом присваиваивание в теле конструктора класса.
Цитата Сообщение от vbloodv Посмотреть сообщение
Что предпочтительнее, какие преимущества у конструкции первого типа?
Думаю, сам поймешь.
1
vbloodv
22 / 22 / 0
Регистрация: 15.12.2012
Сообщений: 314
02.02.2013, 18:24  [ТС] #4
Цитата Сообщение от Nick Alte Посмотреть сообщение
Что ещё более важно, если член не имеет конструктора по умолчанию, то единственный способ его инициализировать - список инициализации.
Немножко не понимаю это момент, если член не имеет конструктора и единственный способ его проинициализировать это через список, т.е для доступа к констуктару нет возможности(к примеру такой член находится в статической библиотеке), но тогда как узнать какие поля класса можно инициализировать через список инициализации ?

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

Цитата Сообщение от vbloodv Посмотреть сообщение
как узнать какие поля класса можно инициализировать через список инициализации
Очень просто - можно инициализировать все. Не включать в список можно только те, которые могут конструироваться по умолчанию, если нужно, чтобы именно по умолчанию они инициализировались.
1
vbloodv
22 / 22 / 0
Регистрация: 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
Jupiter
Каратель
Эксперт С++
6561 / 3982 / 227
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
02.02.2013, 18:52 #7
Цитата Сообщение от vbloodv Посмотреть сообщение
Как будет происходить инициализация такого класса? Если значение переменной id нужно проинициализировать по умолчанию?
id иницализируется мусором
для name - вызван конструктор без параметров
в остальных полях - мусор

порядок инициализации соотвествует порядку объявления переменных в классе
если написать так
C++
1
2
3
Foo::Foo() : id()
{
}
то в id будет 0, для name вызовется конструктор без параметров, в оставшихся полях - мусор.
1
Nick Alte
Эксперт С++
1642 / 1014 / 119
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
02.02.2013, 18:53 #8
По умолчанию встроенные числовые типы имеют неопределённое значение. Под "неопределённым значением" в данном контексте понимается, что там может оказаться какое угодно число, как повезёт. Так что при конструировании Foo по умолчанию вся процедура сведётся к вызову конструктора по умолчанию для string. Если надо, чтобы при конструировании Foo по умолчанию член id принимал определённое значение, пишем соответствующий конструктор с сигнатурой Foo::Foo() и упоминаем id в списке инициализации.
1
MrGluck
Модератор
Эксперт CЭксперт С++
7498 / 4614 / 694
Регистрация: 29.11.2010
Сообщений: 12,634
02.02.2013, 19:38 #9
При использовании списка инициализации для членов вызывается конструктор копирования, объекты конструируются заранее со значениями, переданными им. Если этого не происходит, то сначала вызывается конструктор по-умолчанию, а далее вызывается оператор присвоений. Не говоря о том, что это логически не совсем то, чего мы хотели, это еще и лишние операции. Вдобавок, ссылки и константные члены обязаны быть проинициализированны на момент объявления.
За сим список инициализации стоит использовать всегда, за одним редким исключением, когда требуется множественное присваивание.
1
diagon
Higher
1932 / 1198 / 49
Регистрация: 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
1484 / 1130 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
02.02.2013, 20:08 #12
работает так, как и должен работать. то, что при инициализации вызывается метод, который обращается к еще неинициализированному мемберу - это не вина списка инициализации, что в этой ссылке и написано. так можно и без всяких потоков написать.
0
diagon
Higher
1932 / 1198 / 49
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
02.02.2013, 20:33 #13
Цитата Сообщение от DU Посмотреть сообщение
так можно и без всяких потоков написать.
Ну, тогда оно просто не будет работать. В случае с потоками оно всего лишь иногда не работает, что еще веселее.

Цитата Сообщение от DU Посмотреть сообщение
это не вина списка инициализации
Вина списка инициализации в том, что он инициализирует мемберы не в том порядке, в котором они перечислены в списке.
В целях рефакторинга поменял переменные местами - программа перестала работать. Нет уж, пусть такая ситуация остается в анекдотах.
Хотя, соглашусь, это некритично. Для меня наиболее важно то, что
Цитата Сообщение от diagon Посмотреть сообщение
у него некошерный синтаксис
0
Jupiter
Каратель
Эксперт С++
6561 / 3982 / 227
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
02.02.2013, 20:47 #14
Цитата Сообщение от diagon Посмотреть сообщение
Вина списка инициализации в том, что он инициализирует мемберы не в том порядке, в котором они перечислены в списке.
вот как раз тут все логично, это вина программиста, который не знает язык или пишет код в не в здравом уме
0
MrGluck
Модератор
Эксперт CЭксперт С++
7498 / 4614 / 694
Регистрация: 29.11.2010
Сообщений: 12,634
02.02.2013, 23:52 #15
Цитата Сообщение от diagon Посмотреть сообщение
компайлер это должен соптимизировать(но проверять лень).
думаю это справедливо лишь для POD типов

Список инициализации не виноват в проблемах навроде того, что перечисляют не в том порядке, в каком объявляют в классе, или, если рассматривать проблему в общем случае, используют обращение к неинициализированным переменным.
0
02.02.2013, 23:52
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
02.02.2013, 23:52
Привет! Вот еще темы с ответами:

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

сегодня наконец то понял что такое КЛАСС, и ОБЪЕКТ. понято всё, кроме одного - зачем всё это? в смысле, можно же без этого? так зачем жизнь усложнять? - C++
сегодня наконец то понял что такое КЛАСС, и ОБЪЕКТ. понято всё, кроме одного - зачем всё это? в смысле, можно же без этого? так зачем жизнь...

Зачем биты нужны это меньше байтов но int 32 бита но я не допер зачем это нужно это 4 байта то есть int не может больше 4 байт весить? - C++
Вот еще один вопрос зачем биты нужны это меньше байтов но int 32 бита но я не допер зачем это нужно это 4 байта то есть int не может...

typedef struct Foo или struct Foo - C (СИ)
В чём разница между: typedef struct { int a; }Foo; и struct Foo { int a; }


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.