C ++ temporary object note

Source: Internet
Author: User

C ++ temporary object note

There are two areas in C ++ that have always been vague. The first is the reference, and the second is the temporary object. This may be related to my lack of systematic knowledge and I haven't read C ++ Primer yet. I decided to do this during the winter vacation. I sorted out the C ++ Primer system and made a detailed summary.

If there is any error, please let me know.

Example:

 

# Include
 
  
Using namespace std; void Swap (int a, int B) {int temp; // is the temp in this place a temporary object? Temp = a; a = B; B = temp;} int main (){//...}
 

First, solve the first pitfall: Temporary objects and local variables.

Do not confuse local variables with temporary objects. The variables you can see in the program are not temporary objects.

The temporary object is const and is perceived by the compiler.

Why do we need to summarize the temporary variables? 1. Description:

For me, it makes me uncomfortable, reference, pointer, and temporary variable. On the one hand, it may be that I am not good enough, I did not understand some of the books I read.

For programs, research can improve efficiency. As the name suggests, temporary. The most common example is in the class, because the generation of temporary objects will call the analysis structure and constructor, resulting in a certain amount of overhead.

2. Description of temporary objects:

A temporary object is an unnamed non-heap object.

For some concepts of heap, you can refer to a blog post I have posted, which is a rough introduction. If you have a more detailed understanding of it, you can look at the compilation and computer composition principles, I cannot sell it because I have no contact. You can only briefly talk about what you already know.

I will introduce three situations about the generation of temporary objects in this article. If you feel something else, you may be merged into one.

Three scenarios: 1) type conversion: Example:

 

// A simple example to illustrate the problem. Character statistics function. # Include
 
  
Using namespace std; int CountChar (const string & p, char c) {int count = 0; for (int I = 0; I
  
   
> C; cout <
   
    
Let's take a look at the function calling process in the above program:
    

 

 

Int CountChar (const string & p, char c); // This is the prototype of the function I defined.
CountChar (str, c); // This is the function call statement. Str in my place is obviously an array name, which is inconsistent with my function prototype. Why can the call be successful and run successfully? This part involves the topic to be discussed today, type conversion.

 

First, it is clear that nothing can be converted. We can convert it because the corresponding constructor exists in the string.
    

 

The following example shows how the conversion is implemented.

 

#include
     
      using namespace  std;class Base{private:int x;public:Base(){cout << Using the default Cstor << endl;}Base(int x_x) :x(x_x){cout << Using the defined Cstor << endl;}~Base(){cout << Using the Destructor << endl;}Base(const Base& temp){x = temp.x;cout << Using the Copy Cstor << endl;}Base operator+(const Base& temp){return Base(x + temp.x);}};int main(){//Base b=100;b = 100;system(pause);return 0;}
     
In the above Code, Base B = 100; why is it compiled? The reason is to call the previously defined constructor. If you comment on those lines, this behavior is illegal. The compiler calls the constructor and takes 100 as the parameter to generate a temporary object. Then call the copy constructor for initialization. Note that the term here is initialization rather than value assignment.
In fact, such a statement: int var1 = 10; double var2 = 12.1; then such a statement: double var3 = var1 + var2 also needs to generate a temporary object. Type conversion is required here.

 

2) pass by value: Example:

 

# Include
     
      
Using namespace std; class Base {private: int x; public: Base (int x_x = 0): x (x_x) {cout <Using the Cstor <endl ;}~ Base () {cout <Using the Destructor <endl;} Base (const Base & temp) {cout <Using the Copy Cstor <endl; x = temp. x ;}};/* Base Test (Base temp) {cout <Do nothing <endl; return temp;} * // void Test (Base temp) {...} int main () {Base base_one (1); // call the constructor. // Base base_two = Test (base_one); // The copy constructor Test (base_one); system (pause); return 0;
     
In this case, the Test function is called. What is passed in? Is it base_one itself?

 

During the test, we found that the copy constructor would be called! Why?

This is the second topic today.

Passing by value is not a temporary object generated by calling the copy constructor.

If you do not want to copy data, we recommend that you use references for reference. For more information about references, refer to the previous blog and reference notes.

3) return by value: Example:

 

// Test the temporary objects returned values. # Include
     
      
Using namespace std; class Base {private: int var; public: Base (int v_var = 0): var (v_var) {cout <Using the Constructor <endl ;}~ Base () {cout <Using the Destrucotr <endl;} Base (const Base & other) {this-> var = other. var; cout <Using the Copy Constructor <endl;} friend Base operator + (const Base & p1, const Base & p2); Base operator = (const Base & p) {this-> var = p. var; cout <Using the assignment operator <endl; return (* this) ;}; Base operator + (const Base & p1, const Base & p2) {/* Base tmp; tmp. var = p1.var + p2.var; return tmp; */ret Urn Base (p1.var + p2.var);} int main () {/* Base base_one (3); // One constructor and one Analysis Base base_two (4 ); // same as Base base_three = base_two + base_one; // Copy Cstor is not called here. Base base_four; * // Base b1 = 100; Base b1; b1 = 100; // base_four = base_one + base_two; // you can compare the values assigned and initialized. system (pause); return 0 ;}
     
Let's take a look at this function:

 

 

Base operator+(const Base& p1, const Base& p2){/*Base tmp;tmp.var=p1.var + p2.var;return tmp;*/return Base(p1.var + p2.var);}
Here we can see that I have commented out a return value. If you are interested, you can test two cases.

 

After the test, we can find that when the function returns, it actually calls the copy constructor. Why?

This involves the return value. Returns a copy instead of itself.

Optimization means using references or pointers.

I will not summarize the specific optimization scheme, because it is generally done by the compiler and cannot be tested on different platforms. However, good coding habits can avoid unnecessary waste.

Example:

 

Base operator+(const Base& p1, const Base& p2){/*Base tmp;tmp.var=p1.var + p2.var;return tmp;*/return Base(p1.var + p2.var);}
Here, my return statement is:
return Base(p1.var + p2.var);
You can save a lot of space costs.

 

The second common optimization measure is to make good use of references and pointers.

The last one is initialization and assignment. It is recommended that the assignment be not recommended for initialization.

The following is an example of initialization and assignment:

 

# Include
     
      
Using namespace std; class Base {private: int x; public: Base (int x_x = 0): x (x_x) {cout <Using the Cstor <endl ;}}; int main () {Base b1 (10); // This is called initialization. Base b2; // This is the declaration b2 = b1; // This is the value assignment. // You can compare the two. The difference between direct initialization and initialization after declaration can be seen through the class constructor. /* Int x = 1; // This is the initialization operation. Int y; y = 1; // This is the value assignment. // This area may not show obvious results. For complex examples, you can refer to the above examples */}
     

 

Temporary object lifecycle: generally:

The destruction of temporary objects in C ++ is the last step in the full expression evaluate process.

A complete expression is the exclusive part of a temporary expression. Any temporary object generated by a subexpression can be destroyed only after the complete expression is solved. This is quite common sense. If you are in a nested expression, the temporary objects generated in the process of solving the problem have been destroyed before they are used, it is difficult to carry out the calculation estimation, after all, computers are essentially processing numbers.

Two special cases: 1) when an object is used to initialize an object: Example:

 

# Include
     
      
Using namespace std; class Base {int x; public: Base (int x_x = 0): x (x_x) {} Base (const Base & temp) {x = temp. x; cout <Using the Copy Cstor <endl;} Base operator + (const Base & temp) {return Base (x + temp. x) ;}}; int main () {Base b1 (1); Base b2 (3); Base b3 = b1 + b2; // In this case, b1 + b2 will call the + function, so the function will generate a temporary object, and then call the copy constructor for initialization. // Here we will emphasize the assignment and initialization. If you write it like this, then Base b4; b4 = b1 + b2; // The effect is definitely different from the above initialization. Test by yourself. System (pause); return 0 ;}
     
The above b1 + b2 is used to initialize b3. In this process, the temporary objects generated by the b1 + b2 expression during the solution are not destroyed immediately, instead, it will not be destroyed until it is copied to b3. What if b3 is destroyed? Therefore, the basic rules should be considered at the language level or compiler level.

 

2) When a temporary object is bound with the reference:

The temporary object will be retained to know whether the initialized reference life ends or the life cycle of the temporary object ends.

 

# Include
     
      
Using namespace std; class Base {int x; public: Base (int x_x = 0): x (x_x) {cout <Using the Cstor <
      
       
We have created a reference for the temporary object b1 + b2 above. At this time, the life cycle of the temporary object is consistent with the above mentioned.
       

 

If you find that the debugging result is different from mine, it may be that the compiler is optimized, which does not mean that you are wrong or I am wrong. Of course, you may make mistakes.

 

 

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.