Вопрос по constructor, c++ – Почему постоянный элемент данных класса должен быть инициализирован в конструкторе?

7

Я хочу знать, почему константный член данных класса должен быть инициализирован в конструкторе и почему не где-то еще? Какое влияние это делает, а не делает?

Я также вижу, что толькоstatic constant integral data может быть инициализирован внутри класса, за исключением того, что не члены данных могут быть инициализированы внутри класса.

for eg:- Suppose below is my class declaration

class A{
     int a; // This we can initialize at the constructor or we can set this member by calling "vSet" member function
     const int b;
     static const int c = 10; //This works fine
public:
     A();
     ~A();
     void vSet(int a);
     int iAdd();
     void vDisplay();    
};

And the constructor is defined as mentioned below:-

Edited Section: As previous constructor definition example was wrong

 A::A():a(1),b(9){}

Пожалуйста, поправьте меня, если я ошибаюсь. Заранее спасибо.

Большое спасибо всем вам за ваш ценный совет. Abhineet

Ваш Ответ

7   ответов
3

которые никогда не могут быть изменены. Он инициализируется один раз, а затем сохраняет одно и то же значение навсегда.

Из-за этого вы не можете просто присвоить ему значение где угодно.

Конструктор, однако, это место, где идет инициализация. Итак, здесь есть исключение, и вы можете присвоить значение своим постоянным данным. Вы можете сделать это классическим способом или, как многие говорили, как список инициализации.

Теперь, почему вы не можете сделать это в определении класса (в отличие, скажем, от Java), когда переменная не является статической, - это еще одна проблема, на которую я не знаю ответа.

9

b=9 даже не будет компилироваться, потому чтоb этоconstтак нельзяassigned любая ценность для этого. Так должно бытьinitializedи для этого используйте список инициализации члена как:

A::A() : a(1), b(9) 
{   // ^^^^^^^^^^^^ this is called member-initialization list

}

В C ++ 11 вы можете использовать инициализацию на месте как:

class A{

     int a = 1;       //C++11 only
     const int b = 9; //C++11 only

     static const int c = 10; //This works fine (both in C++03 and C++11)
     //...
};
12

A::A(){
      a = 1;
      b = 9; // Why we need to initialize this only at the constructor. 
   }

not initialization но этоAssignment.
a а такжеb уже построены, и вы назначаете им значения в этом случае.const Квалификатор требует, чтобы переменная не изменялась после ее инициализации, что позволяет этому назначению нарушить этот контракт.

Это инициализация с использованиемMember Initialization list.

A::A():a(1),b(9)
{}

Возможно, вы захотите взглянуть на мой ответ, чтобы узнать разницу:

В чем разница между инициализацией и назначением внутри конструктора?

Что касается другого вопроса, касающегосяonly static constant integral data can be initialized inside the classПожалуйста, прочитайте мой ответ, который объясняет более подробно:

Почему я не могу инициализировать неконстантный статический член или статический массив в классе?

@Abhineet: проверьте мой предыдущий ответ во второй ссылке, он подробно объясняет обоснование и тот факт, что нормы для инициализации в классе ослаблены в C ++ 11.
@Abhineet: Да, вы можете использовать инициализацию на месте в C ++ 11. Смотри мой ответ.
Кроме вышеуказанной области, что вы упомянули. Можем ли мы сделать инициализацию в каком-то другом месте в классе. Заранее спасибо Abhineet
Большое спасибо за ваш ценный совет. Abhineet
6

его значение не может быть изменено. Инициализация в другом месте, кроме конструктора, будет означать инициализацию по умолчанию, за которой следуетassignment, что недопустимо для константы. Это было бы эквивалентно выполнению этого:

const int i; // OK
i = 42; // Error!

Обратите внимание, что в C ++ 11 это нормально делать это:

struct Foo {

  const int i=42;
  const double x = 3.1416;
};

Но это следует тем же правилам, т.е. нет назначения.

1

поэтому они не могут появляться в правой части выражения из-за его константности.

поэтому, когда вы используете это выражение в теле конструктора

A::A()
{
    a = 1;
    b = 9; // Why we need to initialize this only at the constructor. 
}

Вы используете значение const в качестве lvalue, как упоминалось ранее. Факт состоит в том, что вы пытаетесь присвоить новое значение переменной, которой не разрешено изменять ее значение после того, как начался ее срок службы.

Правильный способ присвоения значений постоянному элементу данных находится в списке инициализатора ctor, т. Е. ДО того, как начинается время существования значения элемента (как упомянуто Nawaz):

A::A() :
    a(1),
    b(9)
{
}

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

2

body вашего конструктора, все члены и подобъекты уже инициализированы. Единственное, что конструкторbody можно сделать, чтобыchange их & # x2013; и это, очевидно, не допускается дляconst члены.

Однако вы можете использовать список инициализаторов.

1

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

Похожие вопросы