The C++ standard (section 8.5) says:
If a program calls for the default initialization of an object of a const-qualified type T, T shall be a class type with a user-provided default constructor.
Why? I can't think of any reason why a user-provided constructor is required in this case.
struct B{ B():x(42){} int doSomeStuff() const{return x;} int x; }; struct A{ A(){}//other than "because the standard says so", why is this line required? B b;//not required for this example, just to illustrate //how this situation isn't totally useless }; int main(){ const A a; }
What is the significance of the default constructor? They are used to create objects, which do not have any specific initial value. Is a default constructor automatically provided? If no constructors are explicitly declared in the class, a default constructor is provided automatically by the compiler.
For example, all members of class type, and their class-type members, must have a default constructor and destructors that are accessible. All data members of reference type and all const members must have a default member initializer.
Default Constructors in C++ They are primarily useful for providing initial values for variables of the class. The two main types of constructors are default constructors and parameterized constructors. Default constructors do not take any parameters.
If any constructor is explicitly declared, then no default constructor is automatically generated. If a virtual destructor is explicitly declared, then no default destructor is automatically generated.
The reason is that if the class doesn't have a user-defined constructor, then it can be POD, and the POD class is not initialized by default. So if you declare a const object of POD which is uninitialized, what use of it? So I think the Standard enforces this rule so that the object can actually be useful.
struct POD { int i; }; POD p1; //uninitialized - but don't worry we can assign some value later on! p1.i = 10; //assign some value later on! POD p2 = POD(); //initialized const POD p3 = POD(); //initialized const POD p4; //uninitialized - error - as we cannot change it later on!
But if you make the class a non-POD:
struct nonPOD_A { nonPOD_A() {} //this makes non-POD }; nonPOD_A a1; //initialized const nonPOD_A a2; //initialized
Note the difference between POD and non-POD.
User-defined constructor is one way to make the class non-POD. There are several ways you can do that.
struct nonPOD_B { virtual void f() {} //virtual function make it non-POD }; nonPOD_B b1; //initialized const nonPOD_B b2; //initialized
Notice nonPOD_B doesn't defined user-defined constructor. Compile it. It will compile:
And comment the virtual function, then it gives error, as expected:
Well, I think, you misunderstood the passage. It first says this (§8.5/9):
If no initializer is specified for an object, and the object is of (possibly cv-qualified) non-POD class type (or array thereof), the object shall be default-initialized; [...]
It talks about non-POD class possibly cv-qualified type. That is, the non-POD object shall be default-initialized if there is no initializer specified. And what is default-initialized? For non-POD, the spec says (§8.5/5),
To default-initialize an object of type T means:
— if T is a non-POD class type (clause 9), the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);
It simply talks about default constructor of T, whether its user-defined or compiler-generated is irrelevant.
If you're clear up to this, then understand what the spec next says ((§8.5/9),
[...]; if the object is of const-qualified type, the underlying class type shall have a user-declared default constructor.
So this text implies, the program will be ill-formed if the object is of const-qualified POD type, and there is no initializer specified (because POD are not default initialized):
POD p1; //uninitialized - can be useful - hence allowed const POD p2; //uninitialized - never useful - hence not allowed - error
By the way, this compiles fine, because its non-POD, and can be default-initialized.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With