Class mystring {public: Friend ostream & operator <(ostream & out, const mystring & Str); mystring (const char * s) {assert (s! = NULL); cout <"constructor" <Endl; int SZ = strlen (s); STR = new char [SZ + 1]; strcpy (STR, S );} mystring (const mystring & Other) {cout <"copy constructor" <Endl; int SZ = strlen (Other. str); STR = new char [SZ + 1]; strcpy (STR, other. str);} mystring (mystring & Other) {cout <"rv copy constructor" <Endl; STR = Other. STR; Other. STR = NULL;} mystring & operator = (const mystring & Other) {cout <"operator =" <Endl; If (this = & Other) return * this; if (STR! = NULL) {Delete [] STR; STR = NULL;} int SZ = strlen (Other. str); STR = new char [SZ + 1]; strcpy (STR, other. str); return * This;} mystring & operator = (mystring & Other) {cout <"rv operator =" <Endl; STR = Other. STR; Other. STR = NULL; return * This ;}~ Mystring () {cout <"destructor" <Endl; If (STR! = NULL) {Delete [] STR; STR = NULL ;}} public: char * STR ;}; ostream & operator <(ostream & out, const mystring & Str) {out <Str. STR; Return out;} int main () {vector <mystring> vs;. reserve (10); // avoid the impact of the internal movement of the vector on the following result. push_back (mystring ("ABC"); cout <Endl; mystring SA ("XYZ");. push_back (SA); cout <Endl; mystring Sb ("lmn");. push_back (move (SB); cout <Endl; for_each (. begin (),. end (), [] (mystring & Str) {cout <STR <Endl;}); System ("pause"); Return 0 ;}
Running result:
Constructor
RV copy constructor
Destructor
Constructor
Copy constructor
Constructor
RV copy constructor
ABC
XYZ
Lmn
The vector # push_back function contains two reloads:
Void push_back (T & V) and void push_back (T & V)
When the parameter V is the right value and contains the transfer constructor, the latter is called. Otherwise, the former is called.
The first mystring is a temporary object (unknown). Therefore, the vector # push_back (mystring & V) function is called.
The second mystring is a left value, so the Vector # push_back (mystring & V) is called)
The third mystring is a left value converted to the right value by moving (the caller must realize that the mystring Sb has changed internally and will be used with caution or not ), therefore, Vector # push_back (mystring & V) is called)
The move function converts the left value to the right value. The effect is the same as that of forced conversion. That is, it can also be vs. push_back (mystring &) Sb );
------------------------------------------------
Comment out vs. Reserve (10); in the preceding Code main:
Constructor
RV copy constructor
Destructor
Constructor
RV copy constructor
Destructor
Copy constructor
Constructor
RV copy constructor
RV copy constructor
Destructor
Destructor
RV copy constructor
ABC
XYZ
Lmn
Because the length of a vector is extended by the power of 2, objects must be re-constructed during expansion. After the transfer constructor is used here, the overhead of re-constructing objects is greatly reduced.
After the second mystring is passed in, the vector generates a dynamic array with a length of 2 and copies the first element in the original vector, the transfer constructor and destructor are added to the vector to reduce the overhead.
After the third mystring is passed in, the vector generates a dynamic array with a length of 4 and copies the first and second elements in the original vector, therefore, there are two more pairs of RV copy constructor and destructor.
If there is no mystring without a transfer constructor, the overhead of calling the copy constructor is huge.
Msdn: http://msdn.microsoft.com/en-us/library/dd293665.aspx