Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is a const variable declared as a class member still modifiable?

If a const variable which has been assigned can still be reassigned, then it's not a const? Take for instance:

 struct ss
 {
     const int m = 1024;

     ss()
     {
     }

     ss(int m) : m(m)
     {
     }
 };



ss sa;
ss sb(-1);

cout << sa.m << endl;
cout << sb.m << endl; 

Wow m is not constant after all!

> /* Ouput:
> 
> 1024
> -1
> 
> */
like image 545
user3613229 Avatar asked Jun 15 '14 02:06

user3613229


People also ask

How do you Intialize a const member variable in a class?

To initialize the const value using constructor, we have to use the initialize list. This initializer list is used to initialize the data member of a class. The list of members, that will be initialized, will be present after the constructor after colon. members will be separated using comma.

Do const variables need to be initialized?

A constant variable must be initialized at its declaration. To declare a constant variable in C++, the keyword const is written before the variable's data type. Constant variables can be declared for any data types, such as int , double , char , or string .

Can you declare const and define later?

You don't. Why? Because if it's const, then it can't be changed once the object has been constructed. Note: Even setting it is effectively changing its value from its uninitialized value, which goes against the definition of const to begin with.

How can we initialize an object which is declared as constant data member in another class?

A const variable has to be declared within the class, but it cannot be defined in it. We need to define the const variable outside the class. Here the assignment t = 100 happens in initializer list, much before the class initilization occurs.


1 Answers

 ss(int m) : m(m)
 {
 }

This says that when the class ss is initialized, its member m is initialized using the parameter m. The member m indeed cannot be modified, but it can be initialized, just like any other const object. Note that if we did instead

 ss(int m)
 {
     this->m = m;
 }

then we would have a problem, as ss::m needs to be initialized. And if ss::m were a class with a default constructor, then in

 ss(FooClass m)
 {
     this->m = m;
 }

it's OK to not initialize ss::m explicitly (as it will just be default-constructed), but the line in the body of the constructor would be rejected as it would modify ss::m after it has already been initialized.

Edit: Whoops, I didn't understand your original question.

A brace-or-equal-initializer such as

const int m = 1024;

is only used if the member is not mentioned in the ctor-initializer. In other words, since the default constructor doesn't explicitly initialize m, the value 1024 is used. But ss::ss(int) does explicitly initialize m, so the brace-or-equal-initializer is ignored.

like image 136
Brian Bi Avatar answered Nov 15 '22 04:11

Brian Bi