Constructor call in return expression

class test{ public: int data; test(const test& ){cout<<"INSIDE COPY CON "<<endl;} test(int val = 0) : data(val){ cout<<"INSIDE CON "<<endl; } test testfun(const test& obj) { cout<<"data : "<<data<<endl; //test test3(this->data + obj.data); //cout<<"test3 :"<<test3.data<<endl; //return test3; //This will work only if return type is changed to const ref return test(data + obj.data); } }; int main() { test testO1(1); test testO2(2); test testO3 = testO1.testfun(testO2); cout<<testO3.data<<endl; getchar(); } 

CONCLUSION:

 INSIDE CON INSIDE CON data : 1 INSIDE CON 3 

What happens when a constructor is called in a return statement? Since I can return by value and it works, I think this is not a temporary location. OR it creates the object as temporary and uses the copy constructor to copy the values, in this case why printing inside the copy constructor is not printed.

+4
source share
3 answers

You ask a discerning question.

It depends on the compiler and its associated toolchain to decide what to do, but the main template looks like this. Before calling testfun() caller [ main() in your example] reserves space for test03 on the stack. It then passes the address of test03 to testfun() .

The testfun() function must somehow place the test object at the address provided by the caller. If a function has only one return statement, it can use the storage provided by the caller to create the return value. He should not use his own repository. It can use main() .

Now this strategy does not always work. It usually fails when a function like testfun() has two distinct return statements, one or both of which return a named object rather than a temporary one. In this case, the compiler is forced to make an unnecessary copy in reverse order. However, a more common case is similar to yours, in which testfun() simply builds the return value directly in the place where main() wants it. In this case, the actual copy does not occur.

Thus, before the compiler, you can decide whether the copy constructor will be called upon return in this case.

+4
source

Creates a temporary object, which is then copied to the return value.

But for efficiency, C ++ allows you to reject calls to the copy constructor (or move constructor in C ++ 11), so you should not rely on the side effects of the created copy constructors.

See Optimizing Return Value and Want Speed? Pass by value

+10
source

I will tell you what happens when the return constructor allows you to make a good example for you. I call the class called Counter return in two ways:

return by temporary object:

 // method 1 class Counter { private : int count; public : Counter() : count(0) {} int get_count(void); Counter operator++(int); }; int Counter::get_count() { return count; } Counter Counter::operator++(int) { count++; // create a temp object and assigning count value, then return. Counter temp; temp.count = count; return temp; } 

return by an unnamed temporary object:

 // method 2 class Counter { private : int count; public : Counter() : count(0) {} Counter(int c) : count(c) {} int get_count(void); Counter operator++(int); }; int Counter::get_count() { return count; } Counter Counter::operator++(int) { count++; // call 'Counter(int c)' constructor return Counter(count); } 

main:

 #include <iostream> using namespace std; int main() { Counter c1, c2; c1++; c1++; c2 = c1++; cout << "c1=" << c1.get_count() << endl; cout << "c2=" << c2.get_count() << endl; return 0; } 

The result of both methods is identical, the operator return Counter(count); in the second class does what all three operators did in the first. this operator creates an object of type Counter ; this object has no name; he won't be long enough to be needed. this unnamed object is initialized with the value provided by the count argument, after the nameless object is initialized with the count value, it can be returned.

The effect of the first class same as the second class :

Exit:

 c1= 3 c2= 3 

in the expression c2 = c1++; c1 incremented, then c2 assigned.

0
source

All Articles