Thanks for reading my questions.
I am doing a test regarding to the behavior of the default constructor of a derived class.
For example, here is my structure:
class Base1 {
public:
int a1;
int b1;
virtual void display() const {
cout << "Class Base1" << endl;
}
};
class Derived : public Base1{
public:
int c;
int d;
Derived() :Base1(){
}
};
As you can see, I did not explicit define constructor for the base1 class, so I was expecting that the a1
and a2
would not be initialized.
Base1 b1;
Derived d;
Base1& rb1=d;
cout<<b1.a1<<endl;
cout<<rb1.a1<<endl;
output:
b1.a1 -> -858993460
rb1.a1 -> 0
I am not sure why the int member a1 is intialized when I call the derived class's default constructor.
What's more, if I change the delegate method of the derived class's contructor:
class Derived : public Base1{
public:
using Base2::Base2; //use 'using' to generate the derived class constructor
using Base1::Base1;
int c;
int d;
};
I run the code again:
Base1 b1;
Derived d;
Base1& rb1=d;
cout<<b1.a1<<endl;
cout<<rb1.a1<<endl;
The output changed to:
b1.a1 -> -858993460
rb1.a1 -> -858993460
Anything special about this format Derived() :Base1()
?
Thanks for your comments in advance!
There are certain types that different behavior when value-initialized (i.e. when ()
or {}
is involved) and default-initialized (no initializer is provided, and neither ()
nor {}
were used).
Scalar types are like that (integral, floating-point, enums, pointers, pointers-to-members). Value-initializing zeroes them, while default-initializing leaves them uninitialized.
Some classes are like that. When the default constructor is either implicitly generated or explicitly =default
ed on the first declaration, the choice between those two initialization methods propagates to all members that would otherwise be uninitialized. (Apparently inherited default constructors are allowed here too, I'm not sure if inheriting one has any effect in the first place.)
In your first snippet, Base1
matches this condition, therefore:
Base1 x;
leaves a1
,b1
uninitialized.Base1 x{};
zeroes a1
,b1
.Derived
doesn't match the condition, and it's base Base1
is value-initialized by the Derived
constructor (: Base1()
), so:
Derived x;
and Derived x{}
are the same, they zero a1
,b1
and leave c
,d
uninitialized.In the second snippet, Derived
does match this condition, so:
Derived x;
leaves all members uninitialized.Derived x{}
zeroes all members.