Case Analysis of temporary objects in C++
The knowledge points of this "C++ temporary object case Analysis" article are not quite understood by most people, so the editor summarizes the following, with detailed contents and clear steps, which can be used for reference. I hope you can get something after reading this article. Let's take a look at this "C++ temporary object case Analysis" article.
First, a preliminary study of temporary objects 1. problem
What does the following program output? Why?
The following programs are written for experiments:
# include class Test {int mi;public: Test (int I) {mi = I;} Test () {Test (0);} void print () {printf ("mi =% d\ n", mi);}}; int main () {Test t; t.print (); return 0;}
The output is as follows:
Program intent:
Call Test (int I) with 0 as a parameter in Test ()
Set the initial value of the member variable mi to 0
Running result:
The value of the member variable mi is random
two。 Thinking
Constructor is a special function
Can I call it directly?
Can I call the constructor in the constructor?
What is the behavior of calling the constructor directly?
3. Answer
Calling the constructor directly produces a temporary object
The life cycle of a temporary object is only one statement (after this C++ statement, the temporary object will be destructed and no longer exist)
The scope of a temporary object is only in one statement
The temporary object is the vigilant grey area in C++.
You can write the above code like this to avoid temporary objects:
# include class Test {int mi; void init (int I) {mi = I;} public: Test (int I) {init (I);} Test () {init (0);} void print () {printf ("mi =% d\ n", mi);}}; int main () {Test t; t.print (); return 0;}
The output is as follows:
Let's take a look at a program to get a deep understanding of the temporary object:
# include class Test {int mi; void init (int I) {mi = I;} public: Test (int I) {printf ("Test (int I)\ n"); init (I);} Test () {printf ("Test ()\ n"); init (0);} void print () {printf ("mi =% d\ n", mi) } ~ Test () {printf ("~ Test ()\ n");}}; int main () {printf ("main begin\ n"); Test (); Test (10); printf ("main end\ n"); return 0;}
The output is as follows:
This program well shows that the life cycle of temporary objects has only one statement (after this C++ statement, temporary objects will be destructed and no longer exist).
II. The behavior of the compiler
Modern C++ compilers will try their best to reduce the generation of temporary objects without affecting the final execution result!
Let's look at an example:
# include class Test {int mi;public: Test (int I) {printf ("Test (int I):% d\ n", I); mi = I;} Test (const Test& t) {printf ("Test (const Test& t):% d\ n", t.mi); mi = t.mi } Test () {printf ("Test ()\ n"); mi = 0;} int print () {printf ("mi =% d\ n", mi);} ~ Test () {printf ("~ Test ()\ n");}}; Test func () {return Test (20);} int main () {/ / Test t (10) Equivalent to Test t = Test (10); Test t = Test (10); / / = = > Test t = 10; Test tt = func (); / / = > Test tt = Test (20); = > Test tt = 20; t.print (); tt.print (); return 0;}
The output is as follows:
Pay attention to two points:
You can see from the output that the compiler does not follow the steps of generating temporary objects and initializing t objects with temporary objects (which involves calling the copy constructor), because modern compilers try their best to avoid the generation of temporary objects.
Test t = Test (10); equivalent to Test t = 10; written as Test t = 10; the generation of temporary objects can be eliminated. Because the generation of temporary objects will bring performance problems, Test t = Test (10); it is equivalent to calling the constructor twice, while Test t = 10; if you call the function one less time, the performance is improved.
The above is about the content of this article "C++ temporary object case Analysis". I believe we all have a certain understanding. I hope the content shared by the editor will be helpful to you. If you want to know more about it, please follow the industry information channel.