First, make it clear:
The system has provided the default copy constructor and the = copy operator. That is, the so-called shallow copy.
But sometimes we have to provide our own rewrite. Generally, it is rewritten with pointers.
For a simple example, there is no pointer, so you don't have to rewrite it, just to demonstrate:
[Cpp]
Class Fraction {
Private:
Int fenmu; // denominator
Int fenzi; // molecule
Public:
Fraction (int x, int y ){
Fenzi = x;
Fenmu = y;
}
Fraction (){}
Fraction (const Fraction & fr );
Fraction & operator = (Fraction & p );
Void display (){
Cout <fenmu <"" <fenzi;
}
};
Fraction: Fraction (const Fraction & fr ){
Cout <"test: use copy" <endl;
Fenmu = fr. fenmu;
Fenzi = fr. fenzi;
}
Fraction & Fraction: operator = (Fraction & fr ){
If (this = & fr)
Return * this;
Fenmu = fr. fenmu;
Fenzi = fr. fenzi;
Cout <"test use =" <endl;
Return * this;
}
Int main (){
Fraction f (1, 2 );
Fraction f2 (f); // use copy
// F2.display ();
Fraction f3 = f2; // use copy
Fraction f4, f5;
F5 = f4 = f3; // use =
// F5.display ();
Return 0;
}
Output:
[Cpp]
Test: use copy
Test: use copy
Test use =
Test use =
If a pointer exists, deep copy is required:
[Cpp] view plaincopyprint?
# Include <iostream>
Using namespace std;
Class CA
{
Public:
CA (int B, char * cstr)
{
A = B;
Str = new char [B];
Strcpy (str, cstr );
}
CA (const CA & C)
{
A = C.;
Str = new char [a]; // deep copy
If (str! = 0)
Strcpy (str, C. str );
}
Void Show ()
{
Cout <str <endl;
}
~ CA ()
{
Delete str;
}
Private:
Int;
Char * str;
};
Int main ()
{
Ca a (10, "Hello! ");
Ca B =;
B. Show ();
Return 0;
}
Initializes an object by copying the status of another object of the same class.
Usage: when passed through a value, return through a value, or explicitly copy an object
Value assignment operator
What is returned: * this is generally returned through reference. That is to say, the assignment of the class defined by the user complies with the same conventions as that of the internal type. The assignment can also be used as an expression, that is, cascading.
There are no errors in the Self-assignment syntax, but if you do not implement the assignment operator well, the disaster may be waiting for you.
Therefore, you must ensure that the self-assignment is harmless, that is, you must add the self-assignment detection.
[Cpp]
CAssignment & CAssignment: operator = (const CAssignment &)
{
If (this = &)
Return * this;
//.... Assign a value to the job
}
There are only two results for the value assignment operator: completely successful, the object is left intact, and an exception is thrown.
[Cpp]
CAssignment & CAssignment: operator = (const CAssignment &)
{
If (this = &)
Return * this;
CTemp * t = new CTemp;
//.....
Delete _ tmp;
_ Tmp = t;
Return * this;
}
The derived class uses the value assignment operator.
The value assignment operator in a derived class first calls its direct base class value assignment operator (assign values to the member objects declared in the base class ), then, call the value assignment operator of its member objects (change the Member objects declared in the derived class ). These assignments should usually appear in the same order as the base class and member object in the definition of this class.
[Cpp]
CDerived & CDerived: operator = (const CDerived & r)
{
CBase: operator = (r );
_ C = r. _ c;
Return * this;
}
The correct format of the overload assignment operator is as follows:
The c ++ designer stroustrup has made a lot of effort to make the user's custom type as internal as much as possible.
Similar types of work. For this reason, he made a lot of efforts (such as heavy-duty operators, writing type conversion letters)
Number and copy constructor ). And you should continue.
Let's take a look at the value assignment. When the internal type is used, the value assignment operation can be chained like the following:
Int w, x, y, z; w = x = y = z = 0;
Therefore, you should also be able to link user-defined value assignment operations:
CString w, x, y, z; // MFC "Custom" Type
W = x = y = z = "hello ";
Because the combination of the assignment operators is inherently from right to left, the assignment above can be parsed:
W = (x = (y = (z = "hello"); <=>
W. operator = (x. operator = (y. operator = (z. operator = ("hello "))));
This format indicates that the parameters w. operator =, x. operator = and y. operator = are the first
Operator = return value of the call. Therefore, the return value of operator = must be input.
The input parameter is accepted by the function itself. Generally, operator = the input should be a class object or
Class Object reference, in terms of efficiency, the latter is better than the former, so both input and return should
Is a reference to a class object.
And because there are
Int x, y, z; (x = y) = z;
Therefore, the following statement should be correct.
CString x, y, z; (x = y) = z;
The return value of operator = cannot be const (because the constant cannot be left)
Www.2cto.com
CString x; x = "Hello"; <=>
Const CString temp ("Hello"); // generate a temporary object. Why is it const?
X = temp;
Therefore, to ensure that the preceding statement is true, the operator = input must be const.
So the best implementation is T & operator = (const T &);