Почему члены const должны быть инициализированы в инициализаторе конструктора, а не в его теле?

Почему члены класса, объявленные как const, должны быть инициализированы в списке инициализаторов конструктора, а не в теле конструктора?

Какая разница между двумя?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
67
0
33 020
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

const и ссылочные переменные должны быть инициализированы в той строке, в которой они объявлены.

 class Something  
 {  
     private:  
      const int m_nValue;  
     public:  
      Something()  
      {  
          m_nValue = 5;  
      }  
  };

создаст код, эквивалентный;

const int nValue; // error, const vars must be assigned values immediately  
nValue = 5; 

Назначения значений константных или ссылочных переменных-членов в теле конструктора недостаточно.

C++ предоставляет другой способ инициализации переменных-членов, который позволяет инициализировать переменные-члены при их создании, а не впоследствии. Это делается с помощью списка инициализации.

Вы можете присвоить значения переменным двумя способами: явно и неявно: просмотреть обычную копию в буфер обмена?

int nValue = 5; // explicit assignment  
double dValue(4.7); // implicit assignment  

Использование списка инициализации очень похоже на выполнение неявных присваиваний.

Помните, что список инициализации членов, используемый для инициализации базовых и членских объектов данных, находится в определении, а не в объявлении конструктора.

Подробнее о cpp-учебник и Code Wrangler.

Ответ принят как подходящий

В C++ объект считается полностью инициализированным, когда выполнение входит в тело конструктора.

Вы сказали:

"i wanted to know why const must be intialized in constructor initializer list rather than in it's body ?."

Вам не хватает того, что инициализация встречается в списке инициализации, а назначение встречается в теле конструктора. Шаги по логике:

1) Константный объект может быть только инициализирован.

2) Все члены объекта инициализированы в списке инициализации. Даже если вы явно не инициализируете их там, компилятор с радостью сделает это за вас :-)

3) Следовательно, сложив 1) и 2) вместе, член, который является константой, может иметь значение, присвоенное ему только при инициализации, которая происходит во время списка инициализации.

Поздравляю с первым ответом ... ^ _ ^

paercebal 10.12.2008 12:29

О №2. ASFAIK это верно только для не встроенных типов с заданными по умолчанию ctors. Я бы сказал, что № 1 вместе с тем, что вы указали выше, списка достаточно, чтобы ответить на вопрос. В любом случае, хороший ответ +1 от меня!

Andreas Magnusson 10.12.2008 12:43

@AndreasMagnusson: до C++ 11 инициализация по умолчанию выполнялась для всех членов, не указанных в списке инициализаторов, включая встроенные примитивные типы (для которых инициализация по умолчанию означает «отсутствие инициализации вообще»). Если нет (доступного) конструктора по умолчанию, то это ошибка компиляции. Затем все это изменили инициализаторы скобок или равенства.

Ben Voigt 14.11.2015 07:02

@BenVoigt: Может быть, но это лишняя информация. Для большинства программистов разница между инициализацией переменной как «без инициализации вообще» или без инициализации является чисто вопросом английской семантики. В конце строки, если программист явно не присвоит значение такой переменной, ее значение останется неопределенным (что, в свою очередь, является причиной множества ошибок). Просто сказать, что он инициализируется, означает, что его слишком легко интерпретировать, поскольку он инициализируется 0 (что является имеет место во многих других языках программирования).

Andreas Magnusson 19.11.2015 11:39

Поскольку постоянные переменные и ссылки должны быть инициализированы во время объявления, то есть перед использованием. Но конструкторы присваивают значение переменной, а не инициализируют переменную, поэтому вы должны использовать список инициализаторов для констант и ссылок.

Другие вопросы по теме