![]() |
Модераторы: bsa |
![]() ![]() ![]() |
|
hoz |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 139 Регистрация: 27.6.2013 Репутация: нет Всего: нет |
Часто встречаю такие приёмы, когда переменные инициализируются посредством инициализатора элементов. Хочется понять это просто альтернатива, которая не является необходимой вообще или всё-таки бывает необходима? Например:
переменной x же можно было присвоить значение value внутри конструктора, зачем было объявлять его через : после заголовка? Это сообщение отредактировал(а) hoz - 27.4.2014, 13:49 |
|||
|
||||
BlackSpace |
|
|||
Новичок Профиль Группа: Участник Сообщений: 16 Регистрация: 16.4.2014 Репутация: 1 Всего: 1 |
hoz, да это альтернативный способ, но он боле эффективен для некоторых типов данных, ну а в некоторых случаях без него не обойтись.
В C++ - при создании объекта все члены данных объекта должны быть созданы до вызова конструктора. Список инициализации позволяет задать начальные данные объекту в момент его создания. В процессе создания членов данных, которые сами являются объектами, должны быть вызваны конструкторы. В теле же конструктора, когда происходит присвоение значения объекту - объект не создается, а лишь модифицируется. Думаю тут понятно, что проще сразу присвоить нужные значения членам объекта, чем сначала присвоить то, что есть в конструкторе объекта, а потом менять. Плюс еще для const члена данных не прокатит присваивание. Только инициализация при создании. Также ссылочный тип данных. Вот пример с const.
Это сообщение отредактировал(а) BlackSpace - 27.4.2014, 18:19 |
|||
|
||||
hoz |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 139 Регистрация: 27.6.2013 Репутация: нет Всего: нет |
BlackSpace, я так понимаю данный способ позволяет обойти ограничение того, что константные элементы нельзя изменять в пределах класса. А так ещё до входа в тело конструктора можно инициализировать элемент-данные. Так? А что по поводу большей эффективность для некоторых типов?
А вот тут не совсем понятно. Тут имеется ввиду данные других классов? Т.е. данные, которые не объявлены в теле класса? |
|||
|
||||
BlackSpace |
|
||||||
Новичок Профиль Группа: Участник Сообщений: 16 Регистрация: 16.4.2014 Репутация: 1 Всего: 1 |
hoz, попробую пояснить на примерах.
Пример 1.
Пример 2
1) Все члены данных объекта должны быть созданы до вызова конструктора. 2) Если у объекта класса N есть член данных, который является тоже объектом некого класса M, то до вызова конструктора класса N создается объект класса M. - Но как? С помощью своего конструктора. - А какие значения членам данных объекта класса M присваиваются? Такие, которые заложены в его соответствующем конструкторе. 3) Так вот список инициализации позволяет в момент создания объекта класса N - инициализировать его члены данных. Т.е. инициализировать в данном случае член класса M. По примерам выше поясню разницу. str является объектом класса string. В примере 1 член данных str инициализируется строкой 123 сразу в момент создания объекта класса A. В примере 2 член данных str инициализируется сначала своим конструктором по умолчанию, только потом происходит модификация строки, когда в теле конструктора присваивание происходит. Чувствуете отличие? В первом примере мы не вызывали конструктор по умолчанию для члена данных str, а использовали конструктор класса string с одним аргументом. Вот тут про эффективность думаю понять можно.
Ничего подобного. Ничего в данном случае не обходится. В классе есть константный член и он не меняется. Его надо как-то инициализировать же при создании объекта класса. Вот в списке инициализации и делается это. |
||||||
|
|||||||
borisbn |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 21 Всего: 135 |
Позволю себе дополнить пример BlackSpace
Вывод:
Вот - http://ideone.com/X4AvnZ - можешь "поиграться" -------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
||||
|
|||||
hoz |
|
||||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 139 Регистрация: 27.6.2013 Репутация: нет Всего: нет |
Согласен. Изначально отрабатывают конструкторы объектов, которые являются членами данного класса (В нашем случает объекта класса N). И, отрабатывают они, как я понимаю, в любом случае.
Это понятно.
А как же собственный конструктор класса string ? Судя по ответу, он типа не участвует в инициализации данных класса... А вместо него инициализация происходит напрямую в момент создания объекта класса А. А вот тут я недопонимаю. Сразу не писал, пытался вникунуть, но.. Почему-то тут член данных str инициализируется изначально своим конструктором по умолчанию, а потом уже в теле конструктора. Удивляет меня то, что согласно теории, в любом учебнике сказано, что при создании объекта конструктор вызывается автоматически. Поэтому странно слышать, что в первом случае минуя автоматический конструктор по умолчанию член данных инициализируется сразу заданным значение. Это как понимать?
Как выше я написал, не стыковка выходит. Если согласно документации конструктор вызывается автоматически, и, всегда, то.. как его можно не вызывать? ![]() Это сообщение отредактировал(а) hoz - 1.5.2014, 19:12 |
||||||
|
|||||||
feodorv |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 12 Всего: 45 |
hoz, конструкторов у одного и того же класса может быть несколько. Как с различающимися параметрами, так и без параметров (или с параметрами по умолчанию), последний случай и есть конструктор по умолчанию. Если пользователь явно указал вызов конструктора для какого-либо члена класса, то для него конструктор по умолчанию не вызывается (да и зачем, если и так был вызван другой конструктор с параметрами).
-------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
||||
|
|||||
hoz |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 139 Регистрация: 27.6.2013 Репутация: нет Всего: нет |
Но вызывается то один конструктор как ни крути. Хотя их может быть несколько.. А для остальных вызывается? Имею ввиду если членов класса, скажем так, - 10. Явно инициалируется 1 член. Тогда 9 оставшихся членов-данных инициализируются конструктором по умолчанию, верно? Это сообщение отредактировал(а) hoz - 2.5.2014, 00:17 |
|||
|
||||
BlackSpace |
|
||||||
Новичок Профиль Группа: Участник Сообщений: 16 Регистрация: 16.4.2014 Репутация: 1 Всего: 1 |
hoz,
![]() В моем примере 1 для члена данных str вызывается один конструктор ( с одним параметром в данном случае ). И все. str сразу имеет нужный нам вид - "123". В примере 2 для того же str вызывается сначала конструктор по умолчанию, а лишь потом идет работа по модификации str. Во многих случаях гораздо эффективнее список инициализации, так как он позволяет избежать вызова конструктора по умолчанию ( после которого мы должны модифицировать поле ( str )в теле конструктора ( класса A ) ), а вызвать сразу нужный нам конструктор. А константные или ссылочные поля только в этом списке и можно инициализировать. Мой пример не демонстрирует непосредственно эффективность, но общий принцип должен быть понятен.
Так, приведу еще пример. Правда, 10 классов для примера я не стал писать. Думаю, что для примера сойдет 3 класса, которые будут типами полей в большем классе. Три ( одинаковых для простоты примера ) класса A, B и C. Все имеют конструктор по умолчанию и конструктор с одним параметром. Используемый конструктор можно отследить на стандартном выводе. Два ( почти одинаковых ) класса CommonFirst и CommonSecond, которые содержат поля типов A, B и C. Разница между двумя классами - в конструкторе с тремя параметрами.
Вывод программы
|
||||||
|
|||||||
vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 8 Всего: 56 |
нет, в С++ есть делегирующие конструкторы, которые позволяют сделать цепочку вызова конструкторов сколь угодно длинной. не у всех типов есть конструкторы. К примеру у базовых типов его нет. Для тех у которых есть конструктор по-умолчанию - да, вызывается. |
|||
|
||||
xvr |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 35 Всего: 223 |
||||
|
||||
![]() ![]() ![]() |
Правила форума "C/C++: Для новичков" | |
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Для новичков | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |