C ++ 11 right value reference and std: move statement instance parsing, right value std

Source: Internet
Author: User

C ++ 11 right value reference and std: move statement instance parsing, right value std

Keywords: C ++ 11, right value reference, rvalue, std: move, VS 2015

OS: Windows 10

 

Right-value reference (and supported Move semantics and perfect forwarding) is one of the most important language features added to C ++ 0x. From a practical perspective, it can perfectly solve the temporary object efficiency problem that has been criticized for a long time in C ++. In terms of language itself, it improves the defects of the reference type in C ++ in the left and right values. From the perspective of the Database Designer, it brings a powerful tool to the Database Designer. From the perspective of database users, the "free" efficiency can be improved without moving to the ground...

 

The following example is used to explore the right value reference in depth.

 

1. What is the left value, what is the right value, simply put, the left value can be assigned, and the right value cannot be assigned. The following code is used as an example. "A = getA ();" indicates that the return value of a is the left value and the return value of getA () indicates the right value.

#include "stdafx.h"#include <iostream>class A{public:    A() { std::cout << "Constructor" << std::endl; }    A(const A&) { std::cout << "Copy Constructor" << std::endl; }    ~A() {}};static A getA(){    A a;    return a;}int main(){    A a = getA();        return 0;}

Run the above Code and the output result is as follows:

ConstructorCopy Constructor

We can see that the constructor of A is called once, and the copy constructor is called once. constructor and copy constructor consume A lot. Can we avoid copying constructor here? C ++ 11 has done this.

 

2. Add A mobile constructor. The Code is as follows:

#include "stdafx.h"#include <iostream>class A{public:    A() { std::cout << "Constructor" << std::endl; }    A(const A&) { std::cout << "Copy Constructor" << std::endl; }    A(const A&&) { std::cout << "Move Constructor" << std::endl; } ~A() {}};static A getA(){    A a;    return a;}int main(){    A a = getA();        return 0;}

Run the above Code and output the result:

ConstructorMove Constructor

In this way, the mobile constructor is called instead of the copy constructor. Here we do not see the advantages of mobile construction.

 

3. modify the code and add A member variable to Class A as follows:

#include "stdafx.h"#include <iostream>#include <vector>class B{public:    B() {}    B(const B&) { std::cout << "B Constructor" << std::endl; }};class A{public:    A(): m_b(new B()) { std::cout << "A Constructor" << std::endl; }    A(const A& src) :        m_b(new B(*(src.m_b)))    {         std::cout << "A Copy Constructor" << std::endl;    }    A(A&& src) :        m_b(src.m_b)    {        src.m_b = nullptr;        std::cout << "A Move Constructor" << std::endl;    }    ~A() { delete m_b; }private:    B* m_b;};static A getA(){    A a;    std::cout << "================================================" << std::endl;    return a;}int main(){    A a = getA();    std::cout << "================================================" << std::endl;    A a1(a); return 0;}

Run the above Code and output the result:

A Constructor================================================A Move Constructor================================================B ConstructorA Copy Constructor

"A a = getA ();" calls the mobile structure of a. "A a1 (a);" calls the copy structure of. The copy structure of a requires A deep copy of member variable B, while the moving STRUCTURE OF A does not. Obviously, the moving construction efficiency of A is high.

 

4. the std: move statement can change the left value to the right value to avoid copying the structure. The modification code is as follows:

#include "stdafx.h"#include <iostream>#include <vector>class B{public:    B() {}    B(const B&) { std::cout << "B Constructor" << std::endl; }};class A{public:    A(): m_b(new B()) { std::cout << "A Constructor" << std::endl; }    A(const A& src) :        m_b(new B(*(src.m_b)))    {         std::cout << "A Copy Constructor" << std::endl;    }    A(A&& src) :        m_b(src.m_b)    {        src.m_b = nullptr;        std::cout << "A Move Constructor" << std::endl;    }    ~A() { delete m_b; }private:    B* m_b;};static A getA(){    A a;    std::cout << "================================================" << std::endl;    return a;}int main(){    A a = getA();    std::cout << "================================================" << std::endl;    A a1(a);    std::cout << "================================================" << std::endl;    A a2(std::move(a1)); return 0;}

Run the above Code and output the result:

A Constructor================================================A Move Constructor================================================B ConstructorA Copy Constructor================================================A Move Constructor

"A a2 (std: move (a1);" converts a1 to the right value, so a2 calls the move constructor instead of the copy constructor.

 

5. The assignment operator can also be a move assignment.

# Include "stdafx. h "# include <iostream >#include <vector> class B {public: B () {} B (const B &) {std :: cout <"B Constructor" <std: endl ;}; class A {public: A (): m_ B (new B () {std :: cout <"A Constructor" <std: endl;} A (const A & src): m_ B (new B (* (src. m_ B) {std: cout <"A Copy Constructor" <std: endl;} A (A & src): m_ B (src. m_ B) {src. m_ B = nullptr; std: cout <"A Move Constructor" <std :: Endl;} A & operator = (const A & src) {if (this = & src) return * this; m_ B = new B (* (src. m_ B); std: cout <"operator = (const A & src)" <std: endl; return * this ;} A & operator = (A & src) {if (this = & src) return * this; m_ B = src. m_ B; src. m_ B = nullptr; std: cout <"operator = (const A & src)" <std: endl; return * this ;}~ A () {delete m_ B;} private: B * m_ B;}; static A getA () {A a A; std :: cout <"======================================== ============== "<std:: endl; return a;} int main () {A a = getA (); // move the constructed std :: cout <"======================================== ============== "<std:: endl; A a1 (a); // copy the structure std :: cout <"======================================== ============== "<std:: endl; A a2 (std: move (a1); // move to construct std :: cout <"======================================== ============== "<std:: endl; a2 = getA (); // move the value std :: cout <"======================================== ============== "<std:: endl; a2 = a1; // copy value: return 0 ;}

Run the above Code and output the result:

A Constructor================================================A Move Constructor================================================B ConstructorA Copy Constructor================================================A Move Constructor================================================A Constructor================================================A Move Constructoroperator=(const A&& src)================================================B Constructoroperator=(const A& src)

 

In short, try to add a mobile constructor and a mobile assignment function to the class to reduce the consumption of copy construction and copy assignment.

 

Reference the right value (and its supported

Move

Meaning and perfect forwarding) Yes

C ++ 0x

Major notes to be added

This is from the proposal of this feature in

 

C ++-State of the Evolution

High on the list

You can also see the top spot. From a practical point of view, it can be perfectly solved

C ++

Long-standing

The temporary object efficiency problem. In terms of language itself, it is sound

C ++

The reference type in is left

Defects in the right value.

From the perspective of database designers,

It brings a powerful tool to database designers.

Slave Database

From the user's point of view, the "free" efficiency can be improved without moving one soldier

...

 

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.