there is a serious problem that the destructor is actually being called. Check out the Gotw88, Q3 and A3. I put everything in a small test program (Visual-C ++, so forgive stdafx.h)
// Gotw88.cpp : Defines the entry point for the console application. //
The output of this small program is as follows:
Reference B destroyed Value B destroyed A destroyed
Here is a little explanation of the setting. B is derived from A, but both do not have a virtual destructor (I know this is WTF, but this is important here). CreateB () returns the value of B by value. Currently, it calls CreateB and first saves the result of this call in a reference to const of type A. Then CreateB is called, and the result is stored in a value of type A.
The result is interesting. First, if you store by reference, the correct destructor is called (B); if you store by value, the wrong one is called. The second - if you store in a link, the destructor is called only once, this means that there is only one object. By value, it leads to 2 calls (for different destructors), which means that there are 2 objects.
My advice is to use the const link. At least in Visual C ++, this leads to less copying. If you are unsure of your compiler, use and adapt this test program to test the compiler. How to adapt? Add a copy / move constructor and copy operator.
I quickly added copy and assignment operators for classes A and B
A(const A& rhs) { std::cout<<"A copy constructed"<<std::endl; } A& operator=(const A& rhs) { std::cout<<"A copy assigned"<<std::endl; }
(same for B, just replace each capital A with B)
this leads to the following result:
Reference A constructed B constructed B destroyed Value A constructed B constructed A copy constructed B destroyed A destroyed
This confirms the results given above (note that A constructed results from B built as B are obtained from A and, therefore, the constructor As is called whenever the constructor Bs is called).
Additional tests: Visual C ++ also accepts a non-constant reference with the same result (in this example) as a reference to a constant. In addition, if you use type auto as type, the correct destructor is called (of course), and optimization of the return value works and, in the end, the same result as a constant reference (but, of course, auto has type B, not A )