Which constructor or statement is used in the return (C ++)

I ran this code to experimentally copy the constructor and assignment operator

class AClass { private: int a; public: AClass (int a_) : a(a_) { cout << " constructor AClass(int) " << a << endl; } AClass(const AClass & x) : a(xa) { cout << " copy constructor AClass(const AClass &) " << a << endl; } AClass & operator=(const AClass & x) { a = xa; cout << " AClass& operator=(const AClass &) " << a - endl; return *this; } }; AClass g () { AClass x(8); return x; } int main () { cout << " before AClass b = g() " << endl; AClass b = g(); cout << " after" << endl; cout << " before AClass c(g()) " << endl; AClass c (g()); cout << " after" << endl; } 

and found that for return x; Why? Should the copy constructor or operator = be called

This is the conclusion:

  before AClass b = g () 
  constructor AClass (int) 8
  after

  before AClass c (g ()) 
  constructor AClass (int) 8
  after
+4
source share
6 answers

The compiler is allowed to copy in this case. This is called Return Value Optimization .

+6
source

In C ++, the compiler allows you to delete calls to the copy constructor in almost all circumstances, even if the copy constructor has side effects, such as printing a message. As a consequence, it is also allowed to insert calls into the copy constructor at almost any point to which it refers. This makes written programs to test your understanding of copying and assignment a little more difficult, but means that the compiler can aggressively remove unnecessary copying in real code.

+4
source

This is called "return value optimization". If the object is returned by value, the compiler is allowed to create it in a place accessible to the caller after the function returns; in this case, the copy constructor will not be called.

It is also allowed to consider it as a regular automatic variable and copy it in response, so the copy constructor should be available. Regardless of whether it will be called, it depends on the compiler and optimization settings, so you should not rely on any behavior.

+2
source

This is called a copy of Ellision. The compiler is allowed to copy the Hellenes in almost any situation. The most common case is RVO and NRVO, which basically leads to the construction of return values ​​in place. I will demonstrate the transformation.

 void g (char* memory) { new (memory) AClass(8); } int main () { char __hidden__variable[sizeof(AClass)]; g(__hidden__variable); AClass& b = *(AClass*)&__hidden__variable[0]; cout -- " after" -- endl; // The same process occurs for c. } 

The code has the same effect, but now there is only one instance of AClass.

+2
source

The compiler can optimize the copy constructor call. Basically, it moves an object.

+1
source

If you want to see which constructor the compiler will call, you must defeat RVO. Replace the g() function like this:

 int i; AClass g () { if(i) { AClass x(8); return x; } else { AClass x(9); return x; } } 
+1
source

All Articles