(Conversion) Difference between front ++ and back ++
When I read the document "google c ++ programming style" today, 5.10. Pre-auto-increment and auto-increment: one sentence caught my attention:
Use the prefix format for the iterator and other template objects (++ IThe auto-increment and auto-increment operators. The reason is that the pre-auto-increment (++ I) Is usually higher than the post auto-increment (I ++) Higher efficiency. So I checked the difference between front ++ and back ++..
Note: article 8 of more effective c ++ also specifically addresses the issue. Later, I found that the following article basically refers to its revision. Haha
Difference between front ++ and back ++
The C expert programming is described as follows (P276, people's post and telecommunications Press ):
+ A indicates taking the address of a, adding its content, and placing the value in the register;
A ++ indicates taking the address of a, loading its value into the Register, and then increasing the value of a in the memory. (that is to say, all the values in the register are used during the operation, that is, the value before auto increment)
In addition, I found an article on the Internet to discuss their differences from the perspective of operator overloading, as shown below:
Assume that there is a class Age that describes the Age. This class overload the front ++ and back ++ operators to achieve auto-increment of age.
Class Age {public: Age & operator ++ () // front ++ {++ I; return * this;} const Age operator ++ (int) // post + + {Age tmp = * this; ++ (* this); // use the front + + return tmp;} Age & operator = (int I) // value assignment operation {this-> I = I; return * this;} private: int I ;};
From the code above, we can see that there are three differences between front ++ and back ++:
- Different return types
- Different parameters
- Different codes
- Different Efficiency
Differences in return value types
The front ++ return type is Age &, and the back ++ return type const Age. This means that the front ++ returns the left value, and the rear ++ returns the right value.(There are many discussions about the left and right values. For details, refer to the following section)
The left and right values determine the usage of the front ++ and back ++.
Int main () {Age a; (a ++) ++; // compilation error ++ (a ++); // compilation error a ++ = 1; // compilation error (++ a) ++; // OK ++ (++ a); // OK ++ a = 1; // OK}
The type of ++ is const Age. Naturally, you cannot perform operations such as front ++, back ++, and value assignment on it.
++ A is of the Age type. Of course, you can perform operations such as front ++, back ++, and assignment.
Why is the return type of a ++ a const object?
There are two reasons:
- If it is not a const object, expressions like a (++) ++ can be compiled. However, its effect isViolating our instincts. A actually only adds 1, because the second auto-increment takes effect on a temporary object.
- In addition, for built-in types, expressions such as (I ++) ++ cannot be compiled. Operator overload of the custom type, shouldConsistent behavior with built-in types.
If the return type of a ++ is changed to a non-const object, it will certainly be compiled, but we 'd better not do this.
Why is the return type of ++ a referenced?
The reason for doing so should be: Consistent with the built-in type of behavior. The front ++ always returns the auto-increment object itself. Therefore, the effect of ++ (++ a) Is that a is automatically increased twice.
Differences between parameters
The front ++ has no form parameter, while the back ++ has an int form parameter, but this form parameter is not used. Strange, is there any special purpose?
In fact, there is no special intention, justTo bypass syntax restrictions.
The front ++ and the back ++ operators reload functions. The function prototype must be different. Otherwise, it violates the syntax of "overload functions must have different function prototypes.
Although the front ++ and back ++ return types are different, the return types do not belong to the function prototype. In order to bypass the syntax restriction, we had to add an int parameter to the rear ++.
The reason is that it is so simple that there is no special intention. In fact, you can add a parameter to the front ++. You can also add a double parameter instead of an int parameter. That was the decision at the time.
Differences in code implementation
The implementation of the front ++ is relatively simple. After the auto-increment, you can return * this. Note that you must return * this.
The implementation of post ++ is a little effort-consuming. Because the object before auto-increment is returned, copy the object first, then perform auto-increment, and then return the copy.
In the Age code, the front ++ uses the front ++ to implement auto-increment. This is done to avoid repeated "auto-increment code.
In this example, the auto-increment code is very simple, that is, a row of ++ I, there is no need to do so. However, in other complicated examples of auto-increment logic, it is necessary to do so.
Differences in Efficiency
If you do not need to return the value before auto-increment, the computing effect of the front ++ and back ++ is the same. However, we should still prioritize the use of frontend ++, especially for user-defined auto-increment operations.
The front ++ is more efficient because:A temporary object is generated after ++.
This can also be seen from the code implementation of the plus ++ of Age.
Const Age operator ++ (int) // post ++ {Age tmp = * this; ++ (* this); // use the front ++ return tmp ;}
Obviously, tmp is a temporary object, which causes additional overhead of one constructor and one destructor. Although the compiler can optimize these overhead in some cases. However, we 'd better not rely on compiler behavior.
Therefore, when it is not a built-in type, try to use the front ++, because the efficiency is high (post auto-increment, low efficiency)
Link: http://blog.csdn.net/randyjiawenjie/article/details/6747720