2012-02-25 4 views
19

가능한 중복 :
Deleting pointers in a vectorstd :: vector는 객체에 대한 포인터의 소멸자를 호출합니까?

은 내가 std::vector이 이것을 파괴 될 때, 그것의 각 항목의 소멸자를 호출합니다 알고있다. 그것은 개체에포인터의 소멸자를 호출합니까?

vector<myclass*> stuff; 

물건이 파손되면 물건 내부의 포인터가 가리키는 개별 물체가 파괴됩니까?

+0

[boost :: ptr_vector ] (http://www.boost.org/doc/libs/1_49_0/libs/ptr_container/doc/ptr_vector.html) –

답변

30

번호

어떻게 std::vector는 뾰족한-하는 객체를 파괴하는 방법을 알고 가정된다? delete을 사용해야합니까? delete[]? free? 다른 기능이 있습니까? 지적 객체가 실제로 동적으로 할당되었거나 그것이 하나의 진정한 소유자이며 그것들을 파괴 할 책임이 있다는 것을 어떻게 알 수 있습니까?

std::vector이 가리키는 대상의 진정한 소유자 인 경우 std::unique_ptr을 사용하여 잠재적으로 사용자 지정 삭제자를 사용하여 개체 정리를 처리 할 수 ​​있습니다.

+1

'std :: vector'에 멋대로 될 요소에 대해 파손 함수를 취하는 생성자. 레거시 또는 C API에 유용합니다. 그러나 어쨌든 일을하는 더 좋은 방법은 RAII 클래스로 이런 종류의 리소스를 감싸는 것입니다. – wilhelmtell

+1

@wilhelmtell 당신은 그것에 대한 커스텀 할당자를 쓸 수 있습니다 :) 또는'unique_ptr'에 커스텀 deleter 함수를 주면됩니다. –

+0

@SethCarnegie 예, 댓글을 게시 한 후 몇 초 만에 성공했습니다. 생각하기 전에 말하면서 항상 나에게 일어난다. : -S – wilhelmtell

5

아니오; 자동 객체에 대한 포인터를 저장하면 어떻게 될까요?

vector<T*> v; 
T tinst; 
v.push_back(&tinst); 

벡터가 포인터가 자동 객체가 두 번 파괴 될 가리키는 객체의 소멸자를 호출하면

는 - 벡터가 범위를 벗어나 갔을 때 한 번 한 번 범위를 벗어난 가서 때. 또한, delete으로 할당 해제되지 않아야한다면 어떻게해야합니까? 모든 상황에서 적절하게 행동 할 수있는 방법은 없습니다.

개체가 모두 동적으로 할당 된 경우 new으로 할당 된 경우 벡터와 delete 각 포인터를 수동으로 반복해야합니다. 다른 방법으로, 포인터에 의해 객체가 지적 할당을 해제합니다 스마트 포인터의 벡터를 만들 수 있습니다 올바르게 자신을 말했듯이

vector<shared_ptr<T>> v; 
v.push_back(new T); 
+0

흠. 두 번째 단어 인 "때문에"는 오해의 소지가 있다고 생각합니다. pointees를 삭제하지 않는 것을 정당화하는 책임은 벡터에 없습니다. 오히려 OP는 왜 컨테이너가 포인터 형 요소를 다르게 처리해야하는지 설명해야합니다. 그 대답은 단순한 "아니오"일 수 있습니다. –

+1

@KerrekSB를 제거한 후 :) –

15

, 벡터 요소에 대한 호출 소멸자 않습니다. 따라서 예제에서 벡터 을 "포인터의 소멸자"라고 부릅니다. 그러나 포인터 유형에는 소멸자가 없다는 점을 명심해야합니다. 클래스 타입 만 소멸자를 가질 수 있습니다. 그리고 포인터는 클래스가 아닙니다. 따라서 std::vector은 벡터에 저장된 포인터 개체에 의사 소멸자 호출 구문을 적용한다고 말하는 것이 정확합니다. 결과적으로 아무 작업도 수행하지 않는 포인터 유형의 경우.

이것은 또한 질문의 두 번째 부분에 대한 답변입니다 : 포인터에 의해 가리키는 myclass 개체가 파괴되는지 여부. 아니, 그들은 파괴되지 않는다.

또한 "포인터에 대한 소멸자 호출"(질문의 첫 번째 부분)은 "뾰족한 객체 파괴"(질문의 두 번째 부분)와 같은 것이라고 생각합니다. 실제로 이것은 완전히 다른 두 가지 무관 한 것입니다.

전자와 후자 사이의 링크를 생성하기 위해벡터가 뾰족한 객체를 파괴하도록하려면 일반 원시 myclass * 포인터와는 달리 일종의 "스마트 포인터"에서 벡터를 만들어야합니다. 벡터는 자동으로 "스마트 포인터"의 소멸자를 호출하며,이 소멸자는 차례로 뾰족한 객체를 파괴합니다. 이 "링크"는 "스마트 포인터의"소멸자 내에서만 명시 적으로 구현 될 수 있으므로 일반적인 원시 포인터가 여기에 도움이되지 못하는 이유입니다.

+0

실제로 std :: vector는 아무 것도 파괴하지 않습니다. 할당자가 코드를 수행하지 않습니다. –

+0

+1 하하, 아주 좋아요. –

+0

이것은 포인터가 특별한 경우가 아닌 이유를 보여주는 것으로 받아 들여진 대답이어야합니다. –

관련 문제