The left and right values in c ++

Source: Internet
Author: User

The left value (lvalue) and right value (rvalue) are a relatively obscure concept. Some people may not even have heard of it. But after c ++ 11, this concept has become very important, they are the basis for understanding new meanings such as move () and forward. So what is the left and right values? The left and right values are inherited from c. In c, the left value refers to the variables (expressions) that can appear on the left and right sides of the equal sign ), the right value refers to the variable (expression) that can only appear on the right of the equal sign ). copy the code int a; int B; a = 3; B = 4; a = B; B = a; // invalid. 3 = a; a + B = 4; generally, the variable with a name is the left value (for example, a and B in the above example), while the operation (addition, subtraction, multiplication, division, the intermediate result (with no name) generated by function call return values is the right value, such as 3 + 4 and a + B. For the moment, we can think that the Left value is something that can be searched in the program, and the right value is something that cannot get its address (not completely accurate ). The above concepts become slightly different in c ++. In c ++, each expression generates a left or right value. Correspondingly, this expression is also called "Left value expression" and "Right Value expression ". For the built-in data types (build-in types), the concept of the left and right values is not much different from that of c. The difference lies in the custom type. In addition, such differences are confusing: 1) For built-in types, the right value cannot be modified (non-modifiable) or const, volatile modifier (cv-qualitification ignored) 2) for user-defined types, the right value can be modified through its member functions. For 1), this is the same as c, and 2) it is unique in c ++. Therefore, if you see the following statements in c ++, you may be surprised: copy the code class cs {public: cs (int I): I _ (I) {cout <"cs (" <I <") constructor! "<Endl ;}~ Cs () {cout <"cs destructor, I (" <I _ <")" <endl;} cs & operator = (const cs & other) {I _ = other. I _; cout <"cs operator = ()" <endl; return * this;} int get_ I () const {return I _;} void change (int I) {I _ = I;} private: int I _;}; cs get_cs () {static int I = 0; return cs (I ++);} int main () {// valid (get_cs () = cs (2 )). change (323); get_cs () = cs (2); // operator = () get_cs (). change (32); return 0 ;} Code Generation is somewhat strange. Generally, the custom type in c ++ should be designed to be the same as the built-in type, however, this feature violates this principle. For this feature, we can think like this, but it may be easy to understand: custom types allow member functions, while calling member functions through the right value is allowed, however, the member function may not be of the const type. Therefore, by calling the member function of the right value, the right value, done, may be modified! Note that the right value can be referenced by the const type to point to const cs & ref = get_cs (); it can only be pointed to by reference of the const type: // error cs & ref = get_cs (); when a right value is pointed to by the const reference, its lifecycle is extended, I have talked about its related applications in the previous blog. Click here. The hidden logic here is: the right value cannot be directly converted to the left value (but the left value can be converted to the right value). The two features mentioned above: 1) allows the call of a member function. 2) It can only be pointed to by the const reference. This results in some interesting results, such as copying the code void func (cs & c) {cout <"c:" <c. get_ I () <endl;} // errorfunc (get_cs (); // The correct func (get_cs () = get_cs (); copy the Code where: func (get_cs () = get_cs (); the correct reason is that the cs member function operator = () returns cs &! It is not perfect to allow non-const reference to reference rvalue. In fact, it also causes some problems. For example, the interface for copying constructors is inconsistent. What does this mean? Copy the code class cs {public: cs & operator = (const cs & c) ;}; // write the code class cs2 {public: cs2 & operator = (cs2 & c) ;}; copy the code. The difference between the two statements is that the parameter, the const reference, and the non-const. generally, if you do not need to modify the passed parameters, we usually write them in const reference. However, for copy constructor, we often need to modify the parameter values, such as auto_ptr. Copy the code // similar to auto_ptrclass auto_ptr {public: auto_ptr (auto_tr & p) {ptr _ = p. ptr _; p. ptr _ = NULL;} private: void * ptr _;}; copy the code. Therefore, for auto_ptr, its copy constructor parameter is non const reference. This method should have been encouraged. non-const reference is more flexible than const reference to cope with various situations, so as to maintain consistent interface types. However, if the copy constructor is written like this, the use of rvalue changes greatly. As mentioned above, rvalue cannot be referenced by non-const reference, therefore, copy constructor like auto_ptr cannot pass in rvalue. // error auto_ptr p (get_ptr (); // operator = () Similarly, error. Auto_ptr p = get_ptr (); this is one of the reasons why auto_ptr is not easy to use. To solve this problem, a new reference type is introduced in c ++ 11, which is specifically used to point to rvalue. With this new type, in c ++ 11, the reference types of lvalue and rvalue are separated from each other, and they are the same before. Because of this new type, the new semantics in c ++ 11 is introduced, such as moving () and forward (). Here we will sell a token first, and we will talk about it next time.

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.