Return const subclass reference

What i know

I know that returning a const reference to a temporary object is fine! (e.g. this example :)

class A { public: virtual const A& clone () { return (A()); } virtual std::string name() const { return ("A"); } }; 

Returning a temporary object and binding to a const reference

But!

If I wanted to do this, it's still correct:

 class B : public A { public: virtual const A& clone () { return (B()); } virtual std::string name() const { return ("B"); } }; 

I would have thought yes, but at runtime, the returned object is still treated as object A (as in this example :)

main.cpp

 #include <iostream> #include <string> int main() { B bb; A* aa = &bb; std::cout << aa->clone().name() << std::endl; } 

Output

 valgrind ./a.out ==14106== Use of uninitialised value of size 8 ==14106== at 0x401BF9: main (main.cpp:8) ==14106== Uninitialised value was created by a stack allocation ==14106== at 0x401BF2: main (main.cpp:8) B 

This is a B .. yay .. but this warning is pretty terrifying ....

Edit

Thank you, I know, I see my mistake ... but I would like to know some other things about this ...

When this is done, what exactly happens on the stack?

+6
source share
1 answer

Binding a link to a temporary one extends the lifetime of a temporary ... unless it is not. ยง12.2 [class.temporary] / p5, emphasis added:

The temporary link of the link or the temporary full object of the subobject to which the link is attached is preserved for the duration of the link, except:

  • The temporary binding to the reference element in the ctor-initializer constructor (12.6.2) is maintained until the constructor completes.
  • The temporary reference to the reference parameter in the function call (5.2.2) is stored until the complete expression containing the call is completed.
  • The lifetime of the time reference to the return value in the return statement of function (6.6.3) does not apply; temporary is destroyed at the end of the full expression in the return statement.
  • The temporary reference to the link in new-initializer (5.3.4) is maintained until the completion of the full expression containing the new initializer.

The case in your related question ( std::string foo(); const std::string & s = foo(); ) is fine; the lifetime of the temporary object returned by foo() continues until time s expires. In your code, the temporary one is tied to the returned value, and for the three points mentioned above, its lifetime does not increase, and your function returns a broken link.

Typically, clone() functions should return a pointer to a heap-allocated copy.

+12
source

Source: https://habr.com/ru/post/976508/


All Articles