15th Lesson Rvalue Reference (2) _std::move and move semantics

Source: Internet
Author: User
Tags function prototype

1. Std::move

(1) prototype of Std::move

Template<typename t>TypeName remove_reference<T>::type&& Move (T&& param) {    using returntype = remove_reference<t>::type&&        return static_cast<returntype>(param);}

(2) The role of Std::move

The essence of the ①std::move function is the cast , which unconditionally converts the argument to an rvalue reference , and the Rvalue reference (an anonymous object) returned by the function is an rvalue. Soall that Std::move does is convert its arguments to a right value . This is then used for moving semantics.

② The function just converts its arguments to the right value, except that there is no real move anything . The Std::move application can tell the compiler on the object that the object is eligible for move. That's why Std::move has the name: it makes it easier for a given object to move.

2. Move Semantics

(1) The difference between deep copy and movement

① deep Copy: Copy the Srcobj object to the Destobj object, and you need to copy the Resourse resources to the Destobj object at the same time. This involves a copy of the memory.

② move: Is the transfer of ownership of a resource from one object to another . but only transferred, and no memory is copied. It is visible that the ownership of resource is only transferred from the Srcobj object to the Destobj object without copying.

"Programming experiments" copy and Move semantics

#include <iostream>using namespacestd;//compilation options: g++-std=c++11 test0.cpp-fno-elide-constructorsclasstest{ Public:   int* m;//The memory resources involved//the number of times a function has been called for statistical constructors, destructors, and copy constructs   Static intN_ctor; Static intN_dtor; Static intN_cptor; Static intN_mctor;  Public: Test (): M (New int(0) ) {cout<<"Construct:"<< ++n_ctor <<Endl; } Test (Consttest& t): M (New int(*t.m)) {cout<<"Copy Construct:"<< ++n_cptor <<Endl; }        //Move Constructor    /*Test (test&& t): M (t.m) {t.m = nullptr;    cout << "Move Construct:" << ++n_mctor << Endl; }    */~Test () {cout<<"Destruct:"<< ++n_dtor <<Endl; }};intTest::n_ctor =0;intTest::n_dtor =0;intTest::n_cptor =0;intTest::n_mctor =0;    Test gettemp () {Test T; cout<<"Resource from:"<< __func__ <<": "<< Hex << t.m <<Endl; returnT//The compiler attempts to optimize in several ways. (See the explanation of the Rvo Optimization section later)//1. Preferably optimized by Nrvo. //2. Std::move (Test ()), then call move Constructors//3. If both fail, call copy constructors;}//High-performance swap functionTemplate<typename t>voidSwap (t& A, t&b)    {T tmp (Std::move (a)); A=Std::move (b); b=Std::move (TMP);}intMain () {/*in the experiment, you can compare the two ways of commenting and canceling the annotation move constructor.*/Test T=gettemp (); cout<<"Resource from:"<< __func__ <<": "<< Hex << t.m <<Endl; return 0;}/*Experimental results: 1. Construct:1resource from:gettemp:0x3377f0move construct:1destruct:1move construct:2destruct When no move constructor exists: 2Resource from:main:0x3377f0destruct:32. Construct:1resource from:gettemp:0x5477f0copy construct:1destruct:1copy Construct:2destruct:2resource fro when a move constructor exists M:main:0x547810destruct:3 The experimental results show that although the number of calls to copy construction or mobile construction is not reduced, the copy construction involves a copy of the memory, and the moving structure is only more efficient in the transfer of resources. */

(2) Move semantics

① the generation and destruction of temporary objects and the occurrence of copies is basically transparent to the programmer and does not affect the correctness of the program, but it may affect the execution efficiency of the program and is not easy to detect.

② moving semantics is to transfer resources from one object to another by "stealing" the memory , which is generally more efficient than the copy construction because there is no memory copy .

"Programming Experiment" std::move and moving semantics

#include <iostream>using namespacestd;//compilation options: g++-std=c++11 test2.cpp-fno-elide-constructors//Resource Class (assuming that the class consumes more memory resources)classhugmem{ Public: Hugmem () {cout<<"Hugmem ()"<<Endl;} Hugmem (Consthugmem&) {cout <<"Hugmem (const hugmem&)"<<Endl;} ~hugmem () {cout <<"~hugmem ()"<<Endl;};} ;classtest{Private: Hugmem*HM; Public: Test () {HM=NewHugmem (); cout<<"Test Constructor"<<Endl; } Test (Consttest& obj): HM (NewHugmem (*obj.hm)) {cout<<"Test Copy Constructor"<<Endl; }        //Move ConstructorTest (test&& obj): HM (OBJ.HM)//Resource Transfer{obj.hm= nullptr;//Give up ownership of resourcescout <<"Test Move Constructor"<<Endl; } Test&operator=(Consttest&obj) {        if( This! = &obj) {HM=NewHugmem (*obj.hm); cout<<"operator= (const test& obj)"<<Endl; }        return* This; } Test&operator= (test&&obj) {        if( This! = &obj) {HM=obj.hm; Obj.hm=nullptr; cout<<"operator= (const test&& obj)"<<Endl; }        return* This; }        ~Test () {DeleteHM; //cout << "~test ()" << Endl;    }};         Test Gettest () {test tmp; returntmp//This may be optimized by the compiler, see the Return Value Optimization section}intMain () {Test T1; cout<<"==============================================="<<Endl; Test T2 (T1); //Copy Constructioncout<<"==============================================="<<Endl; Test T3 (std::move (T2)); //Mobile Constructioncout<<"==============================================="<<Endl; T3= Gettest ();//Move AssignmentT1= T3;//Copy Assignmentcout<<"==============================================="<<Endl; Test T4= Gettest ();//->t4 from a temporary object, calls the move construct, and then the temporary object destroyscout <<"==============================================="<<Endl; Test&& T5 = Gettest ();//T5 directly takes over the temporary object, extending its lifespan.//Note the difference from T4    return 0;}/*output Result: e:\study\c++11\15>g++-std=c++11 Test2.cpp-fno-elide-constructorse:\study\c++11\15>a.exehugmem () Test Constructor===============================================hugmem (const hugmem&) test Copy Constructor===== ==========================================test Move constructor=============================================== Hugmem () Test constructortest Move constructoroperator= (const test&& obj) hugmem (const hugmem&) operator= ( Const test& obj) ===============================================hugmem () Test constructortest Move Constructortest move constructor===============================================hugmem () Test ConstructorTest move Constructor~hugmem () ~hugmem () ~hugmem () ~hugmem ( )*/

(3) Other questions

move semantics must be to modify the value of a temporary object , so declaring a move construct should be shaped like test (test&&) and not be declared as test (const test&&).

② by default, the compiler implicitly generates a move constructor, and if you customize the copy constructor, copy assignment function, move assignment function, or any one or more of the destructor, the compiler will no longer provide the default default version.

③ the default move constructor is actually the same as the default copy constructor, which is a shallow copy . In general, if you need to move semantics, you must customize the move constructor.

④ It is dangerous to throw an exception in the move constructor . Since the exception is thrown, it is possible that the move semantics are not completed, which causes some pointers to become hanging pointers. You can add a noexcept keyword for it to ensure that exceptions thrown out of the move constructor call terminate directly to terminate the program.

3. Rvo/nrvo and Std::move

(1) Rvo/nrvo return value optimization: is an optimization technique of the compiler, its function is mainly to eliminate the temporary object created to save the function return value .

classx{ Public: X () {cout<<"Constructor ..."<<Endl;} X (Constx& x) {cout <<"copy Constructor"<<Endl;}};//1. Return anonymous temporary objects by value (RVO)X func () {returnX ();//Rvo Optimization}//2. Return named local objects by value (NRVO)x func () {x x; //return mode 1:    returnX//return named objects by value: Nrvo optimization (compiler automatic optimization, high efficiency!) )//return Mode 2: ( don't do this!) )//return Std::move (x);//x to the right value, intended to be called by the move constructoravoid move constructor to improve efficiency. But in fact,//efficiency is lower than return x because the latter is the compiler defaultoptimized using more efficient nrvo. }//Nrvo pseudo Code:voidFunc (x& result)//notice One more parameter, modify the function prototype{    //The compiler generates a call to the default constructorResult. X::x ();//C + + pseudo code, call x::x ()        return;} X XS= Func ();

(2) The relationship between Std::move and Rvo

the ① compiler uses RVO and Nrvo as much as possible to optimize . Because the return value type of Std::move (localobj) has a reference modifier, it does not meet the RVO criteria in the standard so that the compiler can select only move constructor.

when Rvo optimization is not available , the compiler implicitly calls Std::move (Localobj) to convert,because the value returned is an rvalue, so try to invoke move constructor.

③ if all of these fail , the compiler will call copy constructor.

15th Lesson Rvalue Reference (2) _std::move and move semantics

Related Article

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.