"If you return a value (not a reference) from the function, then bind it to a const reference in the calling function, its lifetime would be extended to the scope of the calling function."
So: CASE A
const BoundingBox Player::GetBoundingBox(void)
{
return BoundingBox( &GetBoundingSphere() );
}
Returns a value of type const BoundingBox
from function GetBoundingBox()
variant I: (Bind it to a const reference)
const BoundingBox& l_Bbox = l_pPlayer->GetBoundingBox();
variant II: (Bind it to a const copy)
const BoundingBox l_Bbox = l_pPlayer->GetBoundingBox();
Both work fine and I don't see the l_Bbox
object going out of scope. (Though, I understand in variant one, the copy constructor is not called and thus is slightly better than variant II).
Also, for comparison, I made the following changes.
CASE B
BoundingBox Player::GetBoundingBox(void)
{
return BoundingBox( &GetBoundingSphere() );
}
with Variants: I
BoundingBox& l_Bbox = l_pPlayer->GetBoundingBox();
and II:
BoundingBox l_Bbox = l_pPlayer->GetBoundingBox();
The object l_Bbox
still does not go out scope. How does "bind it to a const reference in the calling function, its lifetime would be extended to the scope of the calling function", really extend the lifetime of the object to the scope of the calling function ?
Am I missing something trivial here?
Normally a temporary object (such as one returned by a function call) has a lifetime that extends to the end of the "enclosing expression". However, a temporary bound to a reference generally has it's lifetime 'promoted' to the lifetime of the reference (which may or may not be the lifetime of the calling function), but there are a couple exceptions. This is covered by the standard in 12.2/5 "Temporary objects":
The temporary to which the reference is bound or the temporary that is the complete object to a subobject of which the temporary is bound persists for the lifetime of the reference except as specified below. 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.
See the following for more information:
An example that might help visualize what's going on:
#include <iostream>
#include <string>
class foo {
public:
foo( std::string const& n) : name(n) {
std::cout << "foo ctor - " << name + " created\n";
};
foo( foo const& other) : name( other.name + " copy") {
std::cout << "foo copy ctor - " << name + " created\n";
};
~foo() {
std::cout << name + " destroyed\n";
};
std::string getname() const { return name; };
foo getcopy() const { return foo( *this); };
private:
std::string name;
};
std::ostream& operator<<( std::ostream& strm, foo const& f) {
strm << f.getname();
return strm;
}
int main()
{
foo x( "x");
std::cout << x.getcopy() << std::endl;
std::cout << "note that the temp has already been destroyed\n\n\n";
foo const& ref( x.getcopy());
std::cout << ref << std::endl;
std::cout << "the temp won't be deleted until after this...\n\n";
std::cout << "note that the temp has *not* been destroyed yet...\n\n";
}
Which displays:
foo ctor - x created
foo copy ctor - x copy created
x copy
x copy destroyed
note that the temp has already been destroyed
foo copy ctor - x copy created
x copy
the temp won't be deleted until after this...
note that the temp has *not* been destroyed yet...
x copy destroyed
x destroyed
Firstly, the lifetime of temporary object gets extended to the lifetime of const reference that's bound to it, not "to the scope of the calling function" (although maybe that what you meant by that strange wording "the scope of the calling function"). This is what your CASE A
illustrates, where you attach a const reference to a temporary. The temporary continues to live as long as the reference lives. When the reference ends its lifetime, the temporary object gets destroyed as well.
Secondly, your CASE B
is simply ill-formed, non-compilable. Namely, the
BoundingBox& l_Bbox = l_pPlayer->GetBoundingBox();
is illegal. It is illegal in C++ to attach a non-const reference to a temporary. If your compiler allows it, it must be a quirk/extension of your compiler, which has little to do with C++ language.
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