Object replication Problems & amp; lvalue-rvalue & amp; reference, object Replication

Source: Internet
Author: User

Object replication & lvalue-rvalue & reference, object Replication

Passing real parameters to functions and functions return copies of temporary variables by value. Function efficiency is crucial to execution performance.

If such a copy operation is avoided, the execution time may be greatly shortened.

Class CMessage {private: char * m_pMessage; public: void showIt () const {cout <m_pMessage <endl ;} // const CMessage (const char * text = "Default message") {cout <"constrfunction" <endl; size_t length {strlen (text) + 1 }; m_pMessage = new char [length + 1]; strcpy_s (m_pMessage, length + 1, text);} // copy the constructor CMessage (const CMessage & aMess) {cout <"copy constructor" <endl; size_t len {strlen (aMess. m_pMessage) + 1}; this-> m_pMessage = new char [len]; strcpy_s (m_pMessage, len, aMess. m_pMessage);} // overload assignment operator CMessage & operator = (const CMessage & aMess) {cout <"overload assignment operator function" <endl; if (this! = & AMess) {delete [] m_pMessage; size_t length {strlen (aMess. m_pMessage) + 1}; m_pMessage = new char [length]; strcpy_s (this-> m_pMessage, length, aMess. m_pMessage);} return * this;} CMessage operator + (const CMessage & aMess) {cout <"overload addition operator function" <endl; size_t len {strlen (m_pMessage) + strlen (aMess. m_pMessage) + 1 };CMessage message;Message. m_pMessage = new char [len]; strcpy_s (message. m_pMessage, len, m_pMessage); strcat_s (message. m_pMessage, len, aMess. m_pMessage); return message;} // destructor ~ CMessage () {cout <"destructor" <endl; delete [] m_pMessage ;}; int main () {CMessage motto1 {"Amiss is "}; CMessage motto2 {"as good as a mile"}; CMessage motto3; motto3 = motto1 + motto2; motto3.showIt ();}

The running result is as follows:

Constructor // call motto1
Constructor // motto2 call
Constructor // motto3 call
Overload addition Operator Functions
Constructor // call the message object in operator + ()
Copy the constructor // copy the message object to generate a temporary copy of the message
Destructor // message call to destroy a temporary object
Overload assignment operator function // motto3 call operator = ()
Destructor // call a temporary copy of message
Amiss is as good as a mile
Destructor
Destructor
Destructor

Certificate ----------------------------------------------------------------------------------------------------------------------------------------------------------------

Improvement Method:Apply rvalue to reference the form parameter

When the source object is a temporary object and is destroyed immediately after the copy operation, the alternative solution of replication is to steal the memory of the temporary object directed by the m_pMessage member and transfer it to the target object.

In this case, you do not need to allocate more memory for the target object, copy the object, or release the memory of the source object.

After the operation is completed, the source object will be destroyed immediately. Therefore, there is no risk in doing so, but it only speeds up the execution.

The key to implementing this technology is to check when a copy operation is an rvalue.

CMessage (const CMessage & aMess)
{
Cout <"copy constructor" <endl;
Size_t len {strlen (aMess. m_pMessage) + 1 };
This-> m_pMessage = new char [len];
Strcpy_s (m_pMessage, len, aMess. m_pMessage );
}

CMessage (CMessage & aMess)
{
Cout <"" <endl;
M_pMessage = aMess. m_pMessage;
AMess. m_pMessage = nullptr; // This is required to prevent the memory from being deleted.
}

We know that the copy constructor is called when the current object is initialized and the temporary object is returned.

Motto3 = motto1 + motto2; a temporary variable message is generated after the overload addition operator function is called.

Temporary copies required for temporary variable replication increase the running time.

Therefore, the Temporary Variable copy can directly "steal" the memory pointed by the source Temporary Variable object member. Through the comparison of the above two functions, we can see that the lvalue reference parameters have more replication operations.

Is it useless to reference the form of a form parameter with lvalue?

If: motto3 = motto1, we can see that the form of the parameter must be referenced with lvalue. If rvalue is available, the two objects will point to a memory at the same time.

Therefore, rvalue is applicable to temporary variables.

 

You can create an additional overload of the operator = () function as follows:

CMessage & operator = (CMessage & aMess)
{
Cout <"Move assignment operator function called." <endl;
Delete [] m_pMessage;
M_pMessage = aMess. m_pMessage;
AMess. m_pMessage = nullptr; // This is required to prevent the memory from being deleted.
Return * this;
}

CMessage & operator = (const CMessage & aMess)
{
Cout <"overload assignment operator function" <endl;
If (this! = & AMess)
{Delete [] m_pMessage;
Size_t length {strlen (aMess. m_pMessage) + 1 };
M_pMessage = new char [length];
Strcpy_s (this-> m_pMessage, length, aMess. m_pMessage );
}
Return * this;
}

Observe the differences between the two lvalue and rvalue parameters that reference the function of the overload assignment operator:

Motto3 = motto1 + motto2; a temporary variable message is generated after the overload addition operator function is called. When the function returns, rvalue is called to reference the copy constructor of the parameter type,

Generate a temporary copy of the temporary object message.

Call the overload assignment operator function, because it is still a temporary object copy,

Therefore, you can still use the memory pointed to by the object members of the "steal" Source temporary variable. Avoid copying the object members by using the value assignment function.

The temporary object is generated by the compiler. After being used, the Destructor is automatically called for release.

Therefore, we need to observe the Code running and understand it by ourselves.

 

CMessage operator + (const CMessage & aMess)
{
Cout <"overload addition operator function" <endl;
Size_t len {strlen (m_pMessage) + strlen (aMess. m_pMessage) + 1 };
CMessage message;
Message. m_pMessage = new char [len];

Strcpy_s (message. m_pMessage, len, m_pMessage );
Strcat_s (message. m_pMessage, len, aMess. m_pMessage );

Return message;
}

I don't know why the above function does not return a reference, so the reference can avoid unnecessary replication. Isn't it very convenient?

Add reference CMessage&Operator + (const CMessage & aMess)

Running result:

Constructor
Constructor
Constructor
Overload addition Operator Functions
Constructor
Destructor
Overload assignment operator functions
Press any key to continue...

If the program crashes, you cannot continue running the function after you run the function of the overload assignment operator.

Why?

If the returned object is a local variable in the called function, it should not be returned by reference.

Because, when the called function is executed, the local object will call its destructor.

 

If the function returns an object of a class without a public copy constructor (such as an ostream class), it must return a reference to the object.

If the operator = () member function and the copy constructor are defined in the class, the parameter is defined as a constant rvalue reference, make sure that the standard version with the const lvalue reference parameter is also defined.

The compiler will provide their default versions and copy them one by one.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.