Modifying a temporary object

Can someone tell test_method() why the test(2) object is destroyed after calling test_method() ?

 #include<iostream> #include<string> using namespace std; class test { int n; public: test(int n) : n(n) { cout << "test: " << n << endl; } ~test() { cout << "~test: " << n << endl; } test & test_method() { cout << "test_method: " << n << endl; return *this; } }; int main(int argc, const char *argv[]) { cout << "main start" << endl; const test &test1 = test(1); const test &test2 = test(2).test_method(); cout << "main end" << endl; } 

Exit:

 main start test: 1 test: 2 test_method: 2 ~test: 2 main end ~test: 1 
+4
source share
2 answers

test(2).test_method() returns the link attached to test2 , and then the object to which it refers is destroyed at the end of the full expression, since it is a temporary object. This should not be a surprise.

The real surprise is that test1 remains a valid link because it is directly linked to a temporary one, and linking the temporary to the link extends the lifetime from the temporary to the reference variable.

You only need to note that in the case of test(2) temporary object is not attached to anything. He simply used to call some member function, and then his work was done. It does not serve as a babysit, or, in other words, extending life is not transitive with all possible future references.


Here is a simple thought experiment why it would be impossible to have an โ€œarbitrary extension of lifeโ€:

 extern T & get_ref(T &); { T const & x = get_ref(T()); // stuff // Is x still valid? } 

We do not know whether x remains outside the first line. get_ref can do anything. If it is implemented as T & get_ref(T & x) { return x; } T & get_ref(T & x) { return x; } , we can hope for magic, but it could also be like this:

 namespace { T global; } T & get_ref(T & unused) { return global; } 

It is not possible to decide within the original translation unit whether something needs to be extended or not. Thus, the standard at present is that it is a completely trivial local decision that was made only when considering the expression of the reference declaration, what should be the lifetime of a temporary object.

+6
source

Because the C ++ standard requires this behavior. Give the object a name if you want it to persist. It will persist as long as the name.

Change You, your example, test1 is the name you gave to the first object, while the second object did not receive any name at all, and therefore it does not exhaust the evaluation of the expression.

0
source

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


All Articles