Below code shows lifetime of object created in function create()
is extended to the life time of const ref
created in main
, is this correct in all cases? I mean we can extend the life time of temporary in certain cases by creating a reference to it? Or in this specific case the compiler is misbehaving?
It is compiled with MSVC2005
#include <iostream>
class testClass
{
public:
testClass()
{
std::cout << "in testClass " << ((void*)this) << std::endl;
}
~testClass()
{
std::cout << "in ~testClass " << ((void*)this) << std::endl;
}
};
testClass create()
{
return testClass();
}
int main()
{
{
testClass const& obj = create();
std::cout << "we got a const reference to obj " << ((void*)&obj) << std::endl;
}
return 0;
}
Output
in testClass 0018FF13
we got a const reference to obj 0018FF13
in ~testClass 0018FF13
Of course other may get different addresses...In above case i was expecting destructor for the object created with function create()
, will be called before line
std::cout << "we got a const reference to obj " << ((void*)&obj) << std::endl;
is executed.
This is a special case: binding a const reference to a temporary object, stretches its lifetime until that const reference goes out of scope. This is only true for function local const references, e.g. the following will not work:
struct X
{
int const& i
X(int const& i_) : i(i_) {}
};
int f();
int main()
{
X x(f());
int u = x.i; //!
}
During construction of x
, the i_
will be bound to the temporary returned by f
, as will i
, but although it's a const reference, that temporarie's lifetime will not be stretched to that of i
, i.e. the rule does apply here.
Update: as is mentioned in the article and in the comments, the const
is vital. The C++ standard allows binding of temporaries only to const lvalue references and rvalue references, so int& i = f();
is not allowed. However, MSVC has an extension that allows this, and as with other references, the lifetime of the temporary is extended until the reference goes out of scope. I would not recommend to exploit that extension, as it makes the code nonportable. In fact, I would be careful binding temporaries to references, since this feature is not well known and your colleagues might be baffled seeing it work, which means the code will lack readability.