I have the following code:
struct B
{
//B() {}
int x;
int y;
};
void print(const B &b)
{
std::cout<<"x:"<<b.x<<std::endl;
std::cout<<"y:"<<b.y<<std::endl;
std::cout<<"--------"<<std::endl;
}
int main()
{
B b1 = B(); //init1
B b2; //init2
print(b1);
print(b2);
return 0;
}
When I start program (vs2008, debug) I have the following output:
x:0
y:0
--------
x:-858993460
y:-858993460
--------
As you can see b1.x and b1.y have 0 value. why? What's difference between init1 and init2?
When I uncomment B constructor I have the following output:
x:-858993460
y:-858993460
--------
x:-858993460
y:-858993460
--------
Can somebody explain the reason of this behaviour? Tnx in advance.
The constructors can be called explicitly or implicitly. The method of calling the constructor implicitly is also called the shorthand method. Example e = Example(0, 50); // Explicit call.
Constructor chaining can be done in two ways: Within same class: It can be done using this() keyword for constructors in the same class. From base class: by using super() keyword to call the constructor from the base class.
Default Constructors in C++ The two main types of constructors are default constructors and parameterized constructors. Default constructors do not take any parameters. If a default constructor is not provided by the programmer explicitly, then the compiler provides a implicit default constructor.
Default constructor for POD types fills it with zeros. When you explicitly define your own constructor you are not initialize x
and y
and you'll get random values (in VS debug they are filled with exact values, but in release they will be random).
It is according to C++03 Standard 8.5/5:
<...>To value-initialize an object of type T means:
— if T is a class type (clause 9) with a user-declared constructor (12.1), then the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);
— if T is a non-union class type without a user-declared constructor, then every non-static data member and base-class component of T is value-initialized;
— if T is an array type, then each element is value-initialized;
— otherwise, the object is zero-initialized.
B()
is a value-initialization of temporary which will be used in copy-initialization of b1
.
In B b2
there is no initializer specified for an object, so according to C++03 Standard 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; if the object is of const-qualified type, the underlying class type shall have a user-declared default constructor. Otherwise, if no initializer is specified for a non-static object, the object and its subobjects, if any, have an indeterminate initial value; if the object or any of its subobjects are of const-qualified type, the program is ill-formed.
To get zeros for b2
you could write B b2 = {};
.
In both cases, this statement defines b1 and copy-intializes it from a value-initialized temporary B
object.
B b1 = B();
When B
doesn't have a user-declared constructor, value-initializing causes call of B
's members to be value-initalized, and for simple types, such as int
, this means zero-initializing.
When B
does have a user-declared constructor, value-initializing tries to call the default constructor. If the members x
and y
are not listed in the constructor initializer list, then they are left uninitialized.
B b2;
In functions, local objects of POD-type without an initializer are left uninitialized. When you don't define a constructor for B
, it is a POD-class so this applies and the values of b2.x
and b2.y
have indeterminate values.
If the object is of non-POD class type, then it is default-initialized, but if this calls a constructor which leaves its members uninitialized then this makes no difference.
This is value-initialization versus no initialization. If you write
B b1 = B();
you get copy-initialization with a "value-initialized" temporary -- B(). Value-initialization of class-type objects invokes a user-defined constructor (if existant) or otherwise value-initializes the members. Value-initialization of scalar type objects is equivalent to zero-initialization. When you declare your own constructor that doesn't do anything, your scalar members are not initialized.
B b1;
is a default-initialization or no initialization at all (depending on B).
The exact initialization rules are rather complicated. See C++ standard section 8.5 "Initializers".
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