20 minutes to figure out C++11 's rvalue reference (c + + profiling (5))

Source: Internet
Author: User

C + + 11 Adds a lot of new features. a Non-constructor that can have a significant impact on C + + performance and our design class rvalue Reference Mo! I read a lot of information, can say it is not much. I would like to use a simple example to illustrate the need for readers to understand and apply this important language construct.

1. Rvalue reference is reference (i.e. pointer)

For example, the following two statements have exactly the same semantics:

int &&p = 3; //Line 1

const int &CP = 3 //Line 2

2. Rvalue reference point to TEMP variable

The common denominator of the above line1 and line2 is that they all point to temporary variables. The difference is the following two sentences:

p = 5; The content of P becomes 5.

CP = 5; Compile error:CP cannot be changed (constant)

3. Rvalue reference simplifies moving semantics – improves object copy performance

Well, we can now modify the temporary variable (in the dark) by rvalue reference. So what's the use of that? The most important application currently claimed by C++11 is the so-called "moving Semantics (migration semantics)". Take a look at the following example:

Class Simplestring

{

char * _PTR;

Public

simplestring (const char *p);

Simplestring (const simplestring & another);

~simplestring ();

operator Const char * () {return _ptr;}

Simplestring & operator = (const simplestring & another);

static void Test ();

Private

void Getstr (const char *p);

};

simplestring::simplestring (const char *p): _ptr (nullptr)

{

GETSTR (P);

}

Simplestring::simplestring (const simplestring & Another): _ptr (nullptr)

{

Getstr (ANOTHER._PTR);

}

void Simplestring::getstr (const char *p)

{

if (_ptr)

delete [] _ptr;

size_t l=:: strlen (P);

_ptr = new Char[l+1];

:: strcpy_s (This->_ptr, l+1, p);

} 

Simplestring::~simplestring ()

{

if (_ptr)

{

delete [] _ptr;

printf ("Simplestring d ' tr called for \ n");

}

}

Simplestring & simplestring::operator = (const simplestring & Another)

{

Getstr (ANOTHER._PTR);

return *this;

}

Namespace

{

Simple String Factory

Simplestring createstring ()

{

Simplestring temp ("A temp string created!");

return temp;

}

} 

void Simplestring::test ()

{

simplestring ret = createstring ();

printf ("ret is: &s \ n", ret);

}

The above is a simple string class for testing purposes. Suppose we have a function createstringthat returns a created simplestring value. Then assign to the Accept variable ret. What's the problem with this simple logic?

Here is the issue of temporary variables and copy constructor . Here we use simplestring::simplestring (const simplestring & Another), which uses getstr to construct a new pointer _ PTR. Then copy the contents of the temporary variable _ptr .

It's a common practice, but it's expensive. createstring function has built a valid _ptr, why can't we copy pointers?

It turns out that because the temp variable in createstring is a temporary variable , it will be destroyed when the createstring exits, unless we can get his reference or pointer, and then set its _ptr to null. This is a good idea, let's add a function:

void Simplestring::movestr (Simplestring & Another)

{

if (this->_ptr)

Delete this->_ptr;

This->_ptr = another._ptr;

Another._ptr = nullptr;

}

Then rewrite the copy constructor :

Simplestring::simplestring (const simplestring & Another): _ptr (nullptr)

{

Movestr (const_cast<simplestring &> (another)); Line 100

}

In this way, we build only one _ptr, and the test results prove it.

How does it relate to rvalue reference?

I'm not quite happy with the plan for line:

1) We changed the conventional meaning of the original copy constructor , and now as long as you assign a value to another variable, you lose your own value. We hope this function is only suitable for " temporary variables ".

2) Const_casT is not very good, not beautiful.

Now, should we realize the meaning of rvalue reference ?

According to section II,rvalue reference is a pointer to a temporary variable, just the temporary variable that is used to point to the createstring .

It turns out that as long as we add a moving copy constructor in simplestring (note &&):

Simplestring::simplestring (simplestring && another): _ptr (nullptr)

{

Movestr (another);

}

We don't have to change simplestring::simplestring (const simplestring & another) . C + + compiles automatically in this line simplestring ret = createstring () Call our moving constructor simplestring::simplestring ( Simplestring && Another), not our copy constructor.

You might as well try!

Summarize

C++11 uses rvalue reference, which makes it easy to implement moving constructor semantics. This is a similar problem, especially in the STD container usage, which provides the potential for solving the traditional C + + copy of temporary variables.

Appendix: Modified Code

Header:rvalueref.h

class simplestring

{

char * _PTR;

Public :

simplestring (const char *p);

Simplestring (const simplestring & another);

Simplestring (simplestring && another); Moving constructor

~simplestring ();

operator Const char * () {return _ptr;}

Simplestring & operator = (const simplestring & another);

Simplestring & simplestring::operator = (simplestring && another);

static void Test ();

Private :

void Getstr (const char *p);

void Movestr (Simplestring & another);

};

C + +: Rvalue.cpp

#include "stdafx.h"

#include <string.h>

#include <stdlib.h>

#include <stdio.h>

#include <errno.h>

#include "RValueRef.h"

simplestring::simplestring (const char *p): _ptr (nullptr)

{

GETSTR (P);

}

Simplestring::simplestring (const simplestring & Another): _ptr (nullptr)

{

Getstr (ANOTHER._PTR);

}

Moving constructor helps move temp var ' s _ptr to ourselves.

Simplestring::simplestring (simplestring && another): _ptr (nullptr)

{

Movestr (another);

}

void simplestring::getstr (const char *p)

{

if (_ptr)

delete [] _ptr;

size_t l=:: strlen (P);

_ptr = new Char[l+1];

:: strcpy_s (This->_ptr, l+1, p);

}

Simplestring::~simplestring ()

{

if (_ptr)

{

printf ("Simplestring d ' tr called for '%s ' \ n", _ptr);

delete [] _ptr;

}

}

Simplestring & simplestring::operator = (const simplestring & Another)

{

Getstr (ANOTHER._PTR);

return *this;

}

Simplestring & simplestring::operator = (simplestring && another)

{

Movestr (another);

return *this;

}

void simplestring::movestr (simplestring & Another)

{

if (this->_ptr)

Delete this->_ptr;

This->_ptr = another._ptr;

Another._ptr = nullptr; Don ' t forget to does this

}

Namespace

{

Simplestring createstring ()

{

Simplestring temp ("A temp string created!");

return temp;

}

}

void simplestring::test ()

{

simplestring ret = createstring ();

printf ("ret is: &s \ n", ret);

}

20 minutes to figure out C++11 's rvalue reference (c + + profiling (5))

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.