C + + Learning Note 13: operator overloading (assignment operator 2)

Source: Internet
Author: User

Move semantics

Completion of the transfer of ownership, when the copy construction and assignment construction, the target object ownership must be handed over to our new object, the original object will lose ownership, the _p pointer will no longer point to the original array;

Left and right values

C Original Definition

    • Left Value: can appear to the left or right of the assignment number
    • Right value: can only appear to the right of the assignment number

Definition of C + +

    • Lvalue: an expression used to identify a Non-temporary object or a Non-member function
    • Rvalue: an expression used to identify a temporary object or a value unrelated to any object (a pure right value), or an expression that identifies an object that is about to be invalidated (invalid Value)

Lvalue Reference and Rvalue reference

Lvalue reference:&

Rvalue reference:&&

    • Deep copy requires frequent allocation and release of memory, low efficiency
    • Purpose of moving semantics: transfer of ownership without re-structuring and destruction
    • To be compatible with constructors, the move semantics must be a reference, not a pointer or a normal amount
    • A normal reference passes an lvalue to allow the function to modify the target data object internally
    • To differentiate Lvalue references, you must pass Rvalue references when implementing move semantics
    • To ensure that the target data object can be modified, an rvalue reference must be treated as an lvalue reference within the function
classa{ public: A (): _n (0), _p (nullptr) {}ExplicitAintn): _n (n), _p (New int[n]) {} A (intNint*p): _n (n), _p (p) {} a (a&&that ); A&operator= (A &&that ); Virtual~a () {if(_p) {Delete[]_p, _p =nullptr;} } public:    int&operator[](inti); Const int&operator[](intIConst;Private:    int_n; int*_p;}; A::a (A&&that ) {    //nullptr:c++11 a regular object of a predefined null pointer type nullptr_t//can be implicitly converted to any pointer type and bool type, but cannot be converted to an integer type to replace null_n = that._n, _p = that._p, That._n =0, that._p =nullptr; //*this = that;//This code does not call the following overloaded assignment operator function//A named Rvalue reference that is treated as an lvalue inside a function, not a right value//an Anonymous rvalue reference will be treated as a right-hand value, in theory .....//*this = static_cast<a &&> (that);//equivalent to *this = Std::move (that); //the previous line of code can call the following overloaded move assignment operator, but it may cause the program to crash//because this object that this is pointing to may have just allocated memory, the target data object that the _p field points to is undefined}a& A::operator= (A &&that ) {    if(_p)//Deleting this line of code may cause a memory leak        Delete[]_p; //you can test for the same object to avoid copying operations, but with little meaning_n = that._n, _p = that._p, That._n =0, that._p =nullptr; return* this;}

Move Semantic overloading

classa{ public: A (): _n (0), _p (nullptr) {}ExplicitAintn): _n (n), _p (New int[n]) {} A (intNint*p): _n (n), _p (p) {}//you can provide both copy semantics and move semantic versions, which use the constant Lvalue reference//the value of the target data object cannot be modified, while the latter can modifyAConstA &that ); A (a&&that ); A & operator = (const A & that);//Deep Copy version   A & operator = (a && that);//Move an assignment version    Virtual~a () {if(_p) {Delete[]_p, _p =nullptr;} } public:    int&operator[](inti); Const int&operator[](intIConst;Private:    int_n; int*_p;};intmain () {a A (4);  for(inti =0; I <4; i++) {a[i]= i +1; } A B (a);//Call copy Constructorb = a;//Call Normal assignment version//converts an lvalue reference to an rvalue reference, otherwise an lvalue version is called   A c (static_cast<a &&> (A));//call to move constructed version    C = static_cast<a &&> (A);//Call the Move assignment version    return 0;}

Lvalue references can also implement move semantics

classa{ public: A (): _n (0), _p (nullptr) {}ExplicitAintn): _n (n), _p (New int[n]) {} A (intNint*p): _n (n), _p (p) {} a (a& that);//overloading a very heavy version; moving construction semanticsAConstA & that);//overloaded constant version; deep copy construction semanticsA &operator= (A &that);//overloading a very heavy version; moving assignment semanticsA &operator=(ConstA & that);//overloaded constant version; deep copy assignment Semantics    Virtual~a () {if(_p) {Delete[]_p, _p =nullptr;} } public:    int&operator[](intIThrow(std::out_of_range); Const int&operator[](intIConst Throw(std::out_of_range);Private:    int_n; int*_p;}; A::a (A&that ) {_n= that._n, _p = that._p, That._n =0, that._p =nullptr;} A::a (ConstA &that ) {     this->_n =that._n; _p=New int[_n];  for(inti =0; I < _n; i++) {_p[i]=that._p[i]; }}a& A::operator= (A &that ) {_n= that._n, _p = that._p, That._n =0, that._p =nullptr; return* this;} A& A::operator=(ConstA &that ) {     this->_n =that._n; if(_p) {Delete[]_p; } _p=New int[_n];  for(inti =0; I < _n; i++) {_p[i]=that._p[i]; }    return* this;}//main.cppintmain () {A a1;//Default Construction    ConstA a2;//Default ConstructionA A3 (a1);//call a::a (A &), Move ConstructionA A4 (a2);//call a::a (const A &), deep Copy construction//for a very mass, you must transform to a constant to make a deep copyA A5 (const_cast<ConstA &> (a1));//call a::a (const A &)A a6, a7, a8;//Default ConstructionA6 = a1;//call a::operator= (A &), move AssignmentA7 = a2;//call a::operator= (const A &), deep copy AssignmentA8 = const_cast<ConstA &> (a1);//call a::operator= (const A &)    return 0;}

Meaning of rvalue reference

Rvalue reference can use literal as function actual argument

//do not accept text as the actual parameter, because cannot get the left value of textintFint&x) {return++x;}//accept literal as actual argument, pass Rvalue reference//named Rvalue reference as lvalue, anonymous rvalue reference as right value//inside the function theory so, but actually ...intFint&& X) {return++x;}intmain () {//the error code, the operand of the + + operator must be an lvalue//std::cout << ++10 << std::endl; //There may be a problem passing an rvalue reference, but some compilers might use it as a left-hand valueStd::cout << F (Ten) << std::endl;//One by one ?    return 0;}

Meaning of rvalue reference

Avoid writing too many construction and assignment functions

    • Whether it is an lvalue reference or an rvalue reference, 2 pairs (4) Construction and assignment functions are required if both copy semantics and move semantics are provided
    • If you construct an object by providing a member value individually, a single member needs at least 4 constructors and an assignment function, and a double member needs at least 8 constructs and assignment functions
    • Using Rvalue references, You can reduce the amount of code written by a function template

Achieve Perfect forwarding

C + + Learning Note 13: operator overloading (assignment operator 2)

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.