Why constant data member of a class need to be initialized at the constructor?

牧云@^-^@ 提交于 2019-12-12 07:35:31

问题


I want to know why constant data member of a class need to be initialized at the constructor and why not somewhere else? What is the impact of doing so and not doing so?

I also see that only static constant integral data can be initialized inside the class other than that non of the data members can be initialized inside the class.

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){}

Please correct me if I am wrong. Thanks in advance.


回答1:


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

Is not initialization but it is Assignment.
a and b are already constructed and you assign them values in this case. The const qualifier demands that the variable not be changed after its initialization, allowing this assignment would break that contract.

This is Initialization using Member Initialization list.

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

You might want to have a look at this answer of mine to know the difference:

What is the difference between Initializing and Assignment inside constructor?


As for another question, regarding only static constant integral data can be initialized inside the class, please read this answer of mine which explains in greater detail:

Why I can't initialize non-const static member or static array in class?




回答2:


What you're doing is not initialization. It is assignment, so b=9 will NOT even compile, because b is a const, so cannot be assigned any value to it. It should be initialized, and to do that, use member-initialization list as:

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

}

In C++11, you can use in-place initialization as:

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)
     //...
};



回答3:


Because it is constant, it's value cannot be changed. Initializing anywhere else other than the constructor would mean a default initialization, followed by an assignment, which is not permitted for a constant. It would be the equivalent of doing this:

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

Note that in C++11 it is perfectly OK to do this:

struct Foo {

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

But this follows the same rules, i.e there is no assignment.




回答4:


A const data is a data that can never be changed. It is initialized once, and then keeps the same value forever.

Because of that, you can't just assign a value to it anywhere.

The constructor, however, is where initialization goes. So here, there is an exception, and you are able to assign a value to your const data. You can do this the classical way, or as many said, as initialization list.

Now, why you can't do this in the class definition (unlike, say, Java) when the variable is not static is another problem, that I know no answer to.




回答5:


When the body of your constructor is entered, all members and sub-objects are already initialized. The only thing the constructor body can do is to change them – and that is, obviously, not allowed for const members.

You can, however, use an initializer list.




回答6:


You can't initialize const members outside of a constructor because, well, they're const. By definition, you can't modify them after they've been initialized, and after the object has been constructed, anything that tries to set the value is a modification.




回答7:


const values are meant to be rvalues, so they cannot appear on the right part of an expression due its constness.

so, when you use this expression on the constructor's body

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

You're using the const value as a lvalue, just as Als mentioned before. The fact is that you're trying to assing a new value to a variable that isn't allowed to change it's value afther it's lifetime had begun.

The correct way to assign values to a constant data member is in the ctor initializer list, that is, BEFORE the lifetime of the member value begins (as mentioned by Nawaz):

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

Finally, on the C++11 standard you're allowed to initialize all data members where it was declared, just like the static const ones.



来源:https://stackoverflow.com/questions/10647448/why-constant-data-member-of-a-class-need-to-be-initialized-at-the-constructor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!