On some tutorials (e.g. http://www.tutorialspoint.com/cplusplus/cpp_constructor_destructor.htm) I read that the following two codes are equivalent.
First code:
class MyClass1{
public:
int a;
int b;
MyClass1(int a, int b) : a(a), b(b) {};
};
Second code:
class MyClass2{
public:
int a;
int b;
MyClass2(int, int);
};
MyClass2::MyClass2(int a, int b){
this->a = a;
this->b = b;
}
In fact, they give me the same results. But, if I use const
members I'm not able to compile the code anymore.
class MyClass1{
public:
const int a;
const int b;
MyClass1(int a, int b) : a(a), b(b) {};
};
class MyClass2{
public:
const int a;
const int b;
MyClass2(int, int);
};
MyClass2::MyClass2(int a, int b){
this->a = a;
this->b = b;
}
In fact the first class give me no error but in the second class there is an assignment of read-only member
. So, these are the questions:
What is the real difference among the two methods of initialization?
Is using the initialization lists the only method to initialize const
members of a class?
Note: I read online the use of delegating constructors to avoid this problem but it's not clear for me their use and what they really do.
A simple way of looking at it is to make connections with local variables:
Using initializer lists is equivalent to this view of local variables:
int a = 1;
int b = 2;
The second form, assigning them inside constructor is equivalent to this:
int a;
int b;
a = 1;
b = 2;
You can see how this can be a problem with const or with objects that don't have a default constructor:
Ok:
const int a = 1;
const int b = 2;
Not ok:
const int a;
const int b;
a = 1;
b = 2;
e.g.:
class X {
public:
X() = delete; // default constructor deleted
X(int){}; // constructor with an int parameter
};
Ok:
X x(1);
Not ok:
X x;
x = X(1);
class A {
public:
const int a = 10;
};