Wenzhe knows new
---- talk about the constructor again
Author: HolyFire
If you don't know the constructor, let's take a look at "Since the end ---- Construction and Conformation", I will not say more, directly into the topic.
When defining an instance of a class, you can see this form.
Classa a; // Constructor does not require parameters
The constructor of the parameter is not required, called the default constructor.
There are two cases without parameters
1: The constructor has no parameters
2: The constructor has parameters but may not give it.
Class a {
PUBLIC:
A (); // constructor has no parameters
A (int i = 10); // The parameter of the constructor has a default, you can not give it
}
Both of these situations are default constructor, but due to the particularity of the default constructor (he is automatically called), the compiler cannot determine the one you need to call, so it is specified that the default constructor can only have one.
The emergence of the default constructor means that a type can be created without relying on constraints, like some small units, protons, neutrons, and electronics, they have a lot of similarity, no need to distinguish them The information created. Of course, it is not necessary to distinguish the information they have created, and the products produced from the pipeline production are used in the same way, then create their information is basically consistent, that is The second case, the parameters can be used by default.
This example we can give an example, when we create a pointer class, often put him to null value, which is easy to understand, we need a pointer, but now I don't know who, wait until we want to use it When it is, it is not necessarily to know if he points to other objects. In order to simplify the problem, he will set it out at the beginning, but sometimes we need to use the parameters to give points to the object, especially in the temporary When the object is used, it is especially used, then we use a default constructor with a parameter default value.
Classa A (A1); // Conformi-constructor has parameters, and parameters are one of the same type
Such a constructor is called a copy constructor, meaning copies the content of one instance to the newly created instance, why do you want to do this? Let's study.
When we usually use the basic type, you can use the assignment statement to assign the content of an object of the same type to another.
INT A = 3;
INT B;
B = a; // This, there is a content like A in B.
Can also use different types of assignments in the allowable case
INT A = 3;
Long B;
B = a; // This, B can also contain content as a.
We should also use a class as an individual, one type to handle it in design, and in reality, a person's personal information can be written on a different record book, a software can copy a few Part.
So in object-oriented programming, this problem cannot be ignored.
Back to the basic type, the basic type of processing compiler is complete, it is very simple in C , the basic type occupied storage space is continuous, so regardless of the original content, as long as the driver is copied, this negative method Called a bit copy, referred to as a copy.
INT A = 3;
INT B;
Suppose: The storage order of the object in memory is low and low, each memory unit is 1 byte (byte) = 8 bits (BIT)
/ / Suppose this is a (int) storage space
0 3
/ / Assume this is B (int) storage space
??
B = a;
// copy a content to B
0 3
| | | | | |
??
// a
0 3
// b
0 3
Our class is also continuous in memory, using such a copy method to get an expropet of the same type of example. And the compiler we handle this thing (C compiler is really good, it can solve things, you don't have to trouble us), that is, even if we don't define a copy constructor, the compiler will also use it. When you create a copy constructor, the method used is a copy. But is this good, use this new category to work safely, there should be many friends already have doubts.
When can you let the compiler handle your copy constructor yourself.
#include
Using namespace std;
Class a {
Private:
INT X;
Int Y;
Int z;
PUBLIC:
A (): x (0), y (0), z (0) {}
A (int _x = 0, int _y = 0, int _z = 0): x (_x), y (_y), z (_z) {}
Friend Ostream & Operator << (Ostream &, A Const &);
}
Ostream & Operator << (Ostream & Out, A const & arg)
{
OUT << "this is a instance of a" << Endl;
OUT << "MEMBER DATA X IS:" << arg.x << Endl;
OUT << "MEMBER DATA Y IS:" << arg.y << endl;
OUT << "MEMBER DATA Z IS:" << arg.z << Endl;
Return Out;
}
void main ()
{
A A (1, 12, 123);
A b (a);
Cout << "this is a!" << Endl;
COUT << a << endl;
COUT << "B is a copy of a!" << endl;
Cout << b;
}
turn out:
This is a!
This is a instance of a
MEMBER DATA X IS: 1
MEMBER DATA Y IS: 12
MEMBER DATA Z IS: 123
b IS a copy of a!
This is a instance of a
MEMBER DATA X IS: 1
MEMBER DATA Y IS: 12
MEMBER DATA Z IS: 123
It can be seen that the result of the bit copy is correct.
The member variables in the above example are determined during the compilation period, and the position in the memory is relatively relatively relatively fixed. If the content of the member variable is determined during operation, such as a string member variable, he needs to dynamically allocate memory in the heap . Can you work properly and continue to see an example.
#include
#include
#include
Using namespace std;
Class a {
Private:
CHAR * DATA;
PUBLIC: A (): Data (null) {}
A (char * _DATA): DATA (NULL)
{
IF (! _DATA)
Return;
INT length = strlen (_data) 1;
Data = new char [length];
Memcpy (Data, _Data, Length);
}
~ A ()
{
IF (DATA)
DELETE DATA;
}
Void Clear (Void)
{
IF (DATA)
{
MEMSET (DATA, 0, Strlen (DATA);
DELETE DATA;
}
Data = NULL;
}
Friend Ostream & Operator << (Ostream &, A Const &);
}
Ostream & Operator << (Ostream & Out, A const & arg)
{
OUT << "this is a instance of a" << Endl;
IF (arg.data && * arg.data)
OUT << "MEMBER DATA IS:" << arg.data << Endl;
Else
OUT << "" MEMBER DATA IS: NULL << ENDL;
Return Out;
}
void main ()
{
A A ("abcdefg");
A b (a);
Cout << "this is a!" << Endl;
COUT << a << endl;
COUT << "B is a copy of a!" << endl;
Cout << b << endl;
a.clear ();
COUT << "Where a's mem clean!" << endl;
Cout << a;
COUT << "God! B's Mem Clear!" << Endl;
Cout << b << endl;
}
turn out:
This is a!
This is a instance of a
MEMBER DATA IS: ABCDEFG
b IS a copy of a!
This is a instance of a
MEMBER DATA IS: ABCDEFG
WHERE A's MEM CLEAR!
This is a instance of a
MEMBER DATA IS: NULL
God! B's Mem Clear!
This is a instance of a
MEMBER DATA IS: NULL / / No! The release of memory is released in memory.
This is of course due to the copy, the DATA in B is only copied to the DATA in A, and there is no distribution, copying the contents of the string. Obviously, the use of bit copies cannot meet our requirements. It is only necessary to simply copy the value of the member variable, which we call: shallow copy. Now we need to handle the corresponding member variables, use other methods to get the results we need, this is called: deep copy.
This way we need to write copy constructor to achieve a deep copy. #include
#include
#include
Class a {
Private:
CHAR * DATA;
PUBLIC:
A (): Data (null) {}
A (char * _DATA): DATA (NULL)
{
IF (! _DATA)
Return;
INT length = strlen (_data) 1;
Data = new char [length];
Memcpy (Data, _Data, Length);
}
A (a const & arg)
{
IF (! arg.data)
Return;
INT length = strlen (arg.data) 1;
Data = new char [length];
Memcpy (Data, Arg.Data, Length);
}
~ A ()
{
IF (DATA)
DELETE DATA;
}
Void Clear (Void)
{
IF (DATA)
{
MEMSET (DATA, 0, Strlen (DATA);
DELETE DATA;
}
Data = NULL;
}
Friend Ostream & Operator << (Ostream &, A Const &);
}
Ostream & Operator << (Ostream & Out, A const & arg)
{
OUT << "this is a instance of a" << Endl;
IF (arg.data && * arg.data)
OUT << "MEMBER DATA IS:" << arg.data << Endl;
Else
OUT << "" MEMBER DATA IS: NULL << ENDL;
Return Out;
}
void main ()
{
A A ("abcdefg");
A b (a);
Cout << "this is a!" << Endl;
COUT << a << endl;
COUT << "B is a copy of a!" << endl;
Cout << b << endl;
a.clear ();
COUT << "Where a's mem clean!" << endl;
Cout << a;
COUT << "Good! B's Mem Not Clear!" << endl;
Cout << b << endl;
}
turn out:
This is a!
This is a instance of a
MEMBER DATA IS: ABCDEFG
b IS a copy of a!
This is a instance of a
MEMBER DATA IS: ABCDEFG
WHERE A's MEM CLEAR!
This is a instance of a
MEMBER DATA IS: NULL
Good! B's Mem Not Clear!
This is a instance of a
Member data data is: abcdefg // Haha, this is exactly what I want.
If you can use a bit copy, try to handle the compiler yourself to copy your own way, this will increase efficiency. But must be cautious, otherwise it will produce unpredictable results, if there is a member variable in your class, it uses a deep copy, then you must use a deep copy.
In addition, I said in "White Malaysia ---- Inherit", a type of derived class is one of this type. Then.
Class A;
Class B: Public a {
}
B B;
A a (b);
Such a form is correct. In fact, B first slices to degenerate into a temporary variable TEMPB, the type is Class A, and the part of the part of A. The sequential reservation is reserved, and then uses A (TEMPB) such a successful call.
Copy constructor is not available! Cannot replace with other functions
See such an example
Void function (a a);
When the value is transmitted, the parameter is passed, then a temporary variable of Class A will be generated in the stack. If there is no copy constructor, this process can not be completed, if you don't have a light copy or deep copy, then you may get Less than the correct result. If the copy constructor is correct, we can easily get the results we want ---- Parameters passed by value are not affected after the function is executed.
Classa a = a1; // copy constructor
In fact, this is in the form.
Classa A (A1); / / can be changed to this form
2001/9/13
Ding Ning