2014-07-05 2 views
8

은 다음 코드 조각을 고려하십시오왜 개체에서 이동 한 소멸자가 호출 되었습니까?

struct foo { 
    std::string id; 
}; 

int main() { 
    std::vector<foo> v; 

    { 
    foo tmp; 
    v.push_back(std::move(tmp)); 
    } 
} 

LIVE DEMO

코드의 조각은 입증 :

클래스 foo 것입니다의 기본 생성자는 객체의 구성에 대해 호출 할
  1. tmp.
  2. foo 클래스의 이동 생성자는 v.push_back(std::move(tmp)); 문에서 호출됩니다.
  3. 소멸자 class foo이 두 번 호출됩니다.

질문 :

  1. 객체에서 이동 a의 소멸자는 두 번 호출되는 이유는 무엇입니까?
  2. 실제로 이동되는 대상에서 무엇이 이동합니까?
+2

이동 된 개체는 한 번만 소멸됩니다. 모든 객체는 한 번 생성되고 한 번 파괴됩니다. 두 소멸자 호출은'tmp'와 벡터의 객체를위한 것입니다. –

답변

2

이동 된 개체의 소멸자가 두 번 호출되는 이유는 무엇입니까?

제 소멸자 파괴 이동에서부터 tmpmain()의 제 } 범위에서 벗어나면. 두 번째 소멸자가 foo의 이동을 파괴합니다. v이 범위를 벗어날 때 을 v의 끝에 넣고 main()의 끝에 놓습니다.

이동 대상에서 실제로 이동 한 대상은 무엇입니까?

컴파일러 생성 이동 생성자 idstd::string입니다. std::string의 이동 생성자는 일반적으로 실제 문자열을 저장하는 이동 된 객체의 메모리 블록 소유권을 가져오고 이동 된 객체를 유효하지만 지정되지 않은 상태 (실제로는 빈 문자열)로 설정합니다.

+0

"이동 한 후 tmp를 삭제합니다.": 음, push_back 이후에 범위를 벗어나면 ('}') 이동 한 직후가 아니라 ('). 이것은'push_back'과'}'사이에 더 많은 코드가 있다면 중요합니다. –

+0

@AndreKostur 나는'tmp'가 이동되고'tmp'가 파괴되는 사이에 일시적인 연결이 있음을 암시하지 않았습니다. OP의 데모에서 첫 번째 소멸자가 출력 한 내용이 빈 문자열을 인쇄 한 이유와 그 파기 당시의 'tmp'상태를 설명하기위한 것입니다. 그래도 혼란 스러울 수 있습니다. –

관련 문제