I know that returning a const reference of a temporary object is ok! (like this example:)
class A {
public:
virtual const A& clone () { return (A()); }
virtual std::string name() const { return ("A"); }
};
Returning temporary object and binding to const reference
If I would want to do that, It is still correct:
class B : public A {
public:
virtual const A& clone () { return (B()); }
virtual std::string name() const { return ("B"); }
};
I would think yes, but in execution time, the returned object is still considered as a A object (like 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
It's a B.. yay.. but this warning is quite horrifing....
Thanks to you i know see my error... but i would want to know some other things about it...
When this is executed, what exactly in the stack is happening?
Binding a reference to a temporary extends the lifetime of the temporary...except when it doesn't. §12.2 [class.temporary]/p5, emphasis added:
The temporary to which the reference is bound or the temporary that is the complete object of a subobject to which the reference is bound persists for the lifetime of the reference except:
- A temporary bound to a reference member in a constructor’s ctor-initializer (12.6.2) persists until the constructor exits.
- A temporary bound to a reference parameter in a function call (5.2.2) persists until the completion of the full-expression containing the call.
- The lifetime of a temporary bound to the returned value in a function return statement (6.6.3) is not extended; the temporary is destroyed at the end of the full-expression in the return statement.
- A temporary bound to a reference in a new-initializer (5.3.4) persists until the completion of the full-expression containing the new-initializer.
The case in the question you linked (std::string foo(); const std::string & s = foo();
) is OK; the lifetime of the temporary returned by foo()
is extended until s
's lifetime ends. In your code, the temporary is bound to the returned value, and per the third bullet point above, its lifetime is not extended, and your function returns a dangling reference.
Usually speaking, clone()
functions should return a pointer to a heap-allocated copy.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With