In this paper, the C + + constructor for the in-depth exploration for your reference, the specific contents are as follows
1. Intro:
Output statements in the following code output 0, why?
struct Test
{
int _a;
Test (int a): _a (a) {}
Test ()
{
Test (0);
}
};
Test obj;
cout << obj._a << Endl;
Output is:-858993460
2, analysis
the output of the above code is a garbage value, that is, obj calls the constructor and does not initialize the member, although the default parameterless construct test (int a) is called internally, but from the result, the initialization is unsuccessful. What is this for?
When the constructor is executed, Test () does not invoke the test::test (int a) of the "This" object (that is, the Obj object), but instead creates a new temporary instance object with test::test (int a), and then when the statement is executed, The new temporary object will soon be destroyed. As a result, the "this" object is not initialized, the member _a is a garbage value, and later using the "this" object may cause some problems.
3. Emphasis: constructors call each other
After analyzing this topic, we will think of another problem. And that's what we're focused on today:
Class Test
{
int _a;
int _b;
int _c;
Public:
Test (int a, int b): _a (a), _b (b), _c (0) {}
Test (int A, int b, int c);
If we have two constructors in the C + + class, test (int a, int b), and test (int a, int b, int c), respectively. If our constructor test (int A, int b, int c) completes the assignment initialization work for all members (A,B,C), you can write this:
Test::test (int A, int b, int c)
: _a (a)
, _b (b)
, _c (c)
{
}
However, this writing repeats the work of constructor test (int a, int b), which is fine with fewer class members, and if the members are very large, the code is too big and the code is less readable. However, we can see that constructor test (int a, int b) has completed the assignment initialization of member A and member B, and in order to reduce the amount of code, you want to have the constructor of the 3 arguments call the constructor of the 2 parameters, and then execute some of your own code, This is just like a derived class that calls a function with the same name as the base class before executing its own code. But how is this mechanism implemented?
We have come to the conclusion that a constructor calling another constructor does not complete the initialization of the current object, but initializes the temporary object. Here we go to the core question of this article: How do I call another constructor of this class in the constructor to initialize the current object?
method One: use the placement new technique to explicitly call the constructors of 2 parameters in 3 parameters.
The 3 parameter constructor can be implemented in this way:
Test::test (int A, int b, int c)
{
new (this) Test (a, b);
...
}
Constructors are divided into 2 stages of execution: the initialization stage of the initialization list and the assignment stage in the constructor body. The above method is a constructor that invokes 2 arguments in the second phase.
Placement New is an overloaded version of operator new, but we rarely use it. If you want to create an object in an already allocated memory, it is not possible to use new. In other words, placement new allows you to construct an object in an already allocated memory (stack or heap). The void*p in the prototype is actually the first address that points to a allocated memory buffer. The placement new technology is in the form of new (void *p) type (...), which means that the type constructor is called in the memory area referred to in P, which does not have a memory request.
The essence of this method is that at the object address, the constructor that invokes the 2 arguments regenerates a new object and then overwrites the object. This realization method has the suspicion of opportunistic.
method Two: use c++11 new feature--delegate constructor (delegating constructors). Can be called directly in the constructor initialization list, similar to calling the base class constructor.
Test::test (int A, int b, int c): Test (A, B)
{
...
}
The above mentioned that the constructor has 2 stages of execution, and this method is more convenient in the first phase. Note, however, that you cannot connect _c (c) after test (a, b), because after you call the constructor of 2 parameters, the object is already initialized and cannot be placed in the initialization form of another member. The assignment phase can only be placed in the constructor body. This method is currently available only in VS2013.
This method utilizes the new feature in the C++11 standard-the delegate constructor (delegating constructors). At present only VS2013 and above version of the use, this method is very limited, but really convenient.
The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.