Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to understand the right value reference of C++ 11

2025-01-27 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

The purpose of this article is to share with you the understanding of how to quote the right value of C++ 11. The editor thinks it is very practical, so I hope you can learn something after reading this article. Let's take a look at it with the editor.

A very important concept introduced in C++ 11 is right value reference. Understanding right value references is the basis for learning "mobile semantics" (move semantics). To understand the right value reference, you must first distinguish between the left value and the right value.

One of the most common misunderstandings about the left and right values is that the one to the left of the equal sign is the left value, and the one to the right of the equal sign is the right value. Both the left and right values are for the expression. The left value refers to the persistent object that still exists after the end of the expression, and the right value refers to the temporary object that no longer exists at the end of the expression. A convenient way to distinguish between a left value and a right value is to see if you can get an address for the expression, if so, the left value, otherwise the right value. Here are some examples to illustrate.

Int a = 10

Int b = 20

Int * pFlag = & a

Vector vctTemp

VctTemp.push_back (1)

String str1 = "hello"

String str2 = "world"

Const int & m = 1

Excuse me, are the left values or the right values of a, pFlag, * pFlag, vctTemp [0], 100, string ("hello"), str1, str1+str2, m respectively?

Both an and b are persistent objects (which can be addressed) and are left values

Aroomb is a temporary object (you cannot take an address to it), it is the right value

A persistent + first takes a copy of the persistent object a, and then adds the value of the persistent object a to return that copy, and that copy is a temporary object (it cannot be addressed), so it is the right value.

+ + an adds 1 to the value of the persistent object an and returns the persistent object an itself (which can be addressed), so it is the left value.

PFlag and * pFlag are persistent objects (which can be addressed) and are left values

VctTemp [0] calls the overloaded [] operator, and the [] operator returns an int &, which is a persistent object (which can be addressed) and is a left value.

100and string ("hello") are temporary objects (addresses cannot be taken), and are right values

Str1 is a persistent object (which can be addressed) and is the left value

Str1+str2 calls the + operator, and the + operator returns a string (which cannot be addressed), so it is the right value.

M is a constant reference to a right value, but the reference itself is a persistent object (which can be addressed) and is the left value.

After distinguishing between the left value and the right value, let's look at the left value reference. Left-value references can be divided into non-constant left-value references and constant left-value references according to their modifiers.

Non-constant left value references can only be bound to non-constant left values, not to constant left values, non-constant right values, and constant right values. If binding to constant left value and constant right value is allowed, the non-constant left value reference can be used to modify constant left value and constant right value, which clearly violates the meaning of its constant. If binding to a non-constant right value is allowed, it can lead to a very dangerous situation, because the non-constant right value is a temporary object, and a non-constant left value reference may use a temporary object that has been destroyed.

Constant left value references can be bound to all types of values, including nonconstant left values, constant left values, non-constant right values, and constant right values.

As you can see, when using a left value reference, we cannot tell whether the binding is a non-constant right value. So why distinguish between the right values of non-constant quantities, and what are the benefits of distinguishing them? This involves a famous performance problem in C++-copying temporary objects. Consider the following code:

Vector GetAllScores ()

{

Vector vctTemp

VctTemp.push_back (90)

VctTemp.push_back (95)

Return vctTemp

}

When initialized with vector vctScore = GetAllScores (), the constructor is actually called three times. Although some compilers can use RVO (Return Value Optimization) for optimization, optimization can only be done under certain conditions. As you can see, a very common function call above results in the overhead of two additional copy constructors and destructors due to the existence of a copy of the temporary object. Of course, we can also change the form of the function to void GetAllScores (vector & vctScore), but this is not necessarily the form we need. In addition, consider the concatenation operation of the following string:

String S1 ("hello")

String s = S1 + "a" + "b" + "c" + "d" + "e"

When initializing s, it will produce a large number of temporary objects and involve a large number of string copy operations, which will obviously affect the efficiency and performance of the program. How to solve this problem? If we can determine that a value is a non-constant right (or a left value that will not be used later), then when we make a copy of a temporary object, we can simply "steal" a pointer to the actual data (similar to auto_ptr in STL, which transfers ownership) without copying the actual data. The right value reference introduced in C++ 11 can be used to identify a non-constant right value. C++ 11 uses & for the left value reference and & & for the right value reference, such as:

Int & a = 10

Right value references can also be divided into non-constant right value references and constant right value references according to their modifiers.

Non-constant right value references can only be bound to non-constant right values, but cannot be bound to non-constant left values, constant left values and constant right values (it can be bound to non-constant left values and constant left values in the VS2010 beta version, but it is not allowed in the official version for security reasons). If you allow binding to a non-constant left value, you may mistakenly steal the data of a persistent object, which is very dangerous; if you allow binding to a constant left value and a constant right value, the non-constant right value reference can be used to modify the constant left value and constant right value, which clearly violates the meaning of the constant.

Constant right value references can be bound to non-constant right values and constant right values, but not to non-constant left values and constant left values (for the same reason).

With the concept of right-value reference, we can use it to implement the following CMyString class.

Class CMyString

{

Public:

/ / Constructor

CMyString (const char * pszSrc = NULL)

{

Cout

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report