2012-05-31 4 views
4

test_method() 호출 후 test(2) 개체가 파괴 된 이유를 누가 알 수 있습니까?임시 개체 Modyfying

#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; 
} 

출력된다 :

main start 
test: 1 
test: 2 
test_method: 2 

~test: 2 
main end 
~test: 1 
+0

'std :: cout'이 버퍼되어 있으므로 디버그가 더 이상 필요하지 않습니다. – triclosan

답변

6

test(2).test_method()test2에 결합 된 기준, 후 전체 식 끝에 파괴 참조 처 오브젝트를 반환 그것은이 때문에 임시 개체. 놀랄 일이 아닙니다.

진짜 놀람은 임시 결합 직접이고, 참조에 임시가 기준 변수의 임시의 수명을 연장 결합 때문에 test1가 유효한 참조로 남아 있다는 것이다.

test(2) 경우에는 임시 개체가 아무 것도 바인딩되지 않습니다. 그것은 단지 일부 멤버 함수를 호출하는 데 사용되며 작업이 완료됩니다. 그것은 회원 기능을 "보살 피지"않습니다. 다시 말해, 평생 연장은 모든 미래의 가능한 참조를 통해 이행 적이 지 않습니다.

extern T & get_ref(T &); 

{ 
    T const & x = get_ref(T()); 

    // stuff 

    // Is x still valid? 
} 

x이 첫 번째 줄 이상 유효 경우 우리는 아무 생각이 :


다음은 실제로 "임의의 수명 연장을"이 불가능할 왜 간단한 사고 실험이다. get_ref 뭐든지 할 수 있습니다. 이 T & get_ref(T & x) { return x; }로 구현이라면, 우리는 마법에 대한 희망 수도 있지만, 그것은 또한이 될 수있다 :

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

아무것도 확장 될 필요 여부 원래의 번역 단위에서 결정하는 것은 불가능하다. 그래서 표준이 현재 가지고있는 방식은 참조 선언 표현식을 볼 때, 단지 임시 객체의 수명이 얼마인지를 결정할 때 만들어지는, 완전히 사소한 지역 결정입니다.

+0

멋지게 설명했습니다. 이것이 정의 된 표준 섹션을 알고 있습니까? – juanchopanza

+0

@ juanchopanza : C++ 11 12.2/5. –

0

C++ 표준에는이 동작이 필요하기 때문입니다. 원할 경우 개체에 이름을 지정하십시오. 그것은 이름만큼 오래 지속될 것입니다.

편집 : 당신은 예를 들어, test1 두 번째 목적은 전혀 이름을 얻을 수 없다, 그래서는 식의 평가를 오래 버틸하지 않는 반면에 당신이 첫 번째 개체에 준 이름입니다.