모든 것이 소유권입니다. 엔티티 (함수 또는 객체)는 해당 엔티티의 작업 인 경우 포인터를 "소유"한다고 말하여 포인터가 삭제되었음을 보증합니다. new
을 사용할 때마다 누군가 어딘가에이 반환 된 포인터의 소유권을 가져야합니다. 그렇지 않은 경우 메모리 누수가 발생합니다.
모든 종류의 스마트 포인터의 목적은 어떤 형태의 소유권을 모델링하는 것입니다. 스마트 포인터의 소멸자는 포인터의 삭제를 트리거 할 수 있습니다.
std::auto_ptr
(복사하지 않는 한) 단일 소유권을 모델로합니다. 즉, auto_ptr
인스턴스가있는 모든 엔티티는 해당 포인터의 파기를 발생시키는 엔티티입니다. 해커 덕분에 auto_ptr
을 복사하면 실제로 복사 된 개체의 소유권이 복사 할 개체로 이전됩니다 (참고 : 절대로이 작업을 수행하지 마십시오).
그래서, 당신이있는 경우이 :
std::auto_ptr<int> p1 = new int(4);
이 파괴 될 보장 (너무 오래 잡고 실체가 제대로 정리 될 때). p1
이 스택에서 떨어지면 포인터가 삭제됩니다. p1
이 클래스의 구성원이면 해당 클래스 인스턴스가 삭제되면 포인터가 삭제됩니다. 포인터의 유효 기간이 유효합니다. Boost에는 실제로 이라는 복사 할 수없는 동일한 기능이 있습니다.
모든 종류의 스마트 포인터를 사용할 때 준수해야하는 몇 가지 규칙이 있습니다. 이것이 가장 중요합니다.
규칙 # 1 :. 당신이 알몸 포인터에서 스마트 포인터의 인스턴스를 생성하는 경우, 당신은 지금 이니 객체가 현재이 포인터의 소유권이 없다 ", IS 무슨 말을 당신 소유권을주고, 스마트 포인터. " 그것이 알몸 포인터에서 스마트 포인터 개체를 구성한다는 의미입니다.
이 코드는 규칙 # 1의 위반 :
std::auto_ptr<int> p1 = new int(4);
std::auto_ptr<int> p2 = p1.get();
auto_ptr::get()
기능은 포인터를 반환, 그래서 이것은 법적 C++ 코드 (이 컴파일)입니다. 그러나 p1
과 p2
은 모두 포인터를 소유하고 있다고 생각합니다. auto_ptr
모델은 단일 - 소유권 만 허용되지 않으므로 허용되지 않습니다. p2
이 파괴되면 포인터가 삭제됩니다. 그런 다음 p1
이 파괴되면 같은 포인터를 삭제하려고 시도합니다.
이제 우리는 규칙 # 1에 대해 매우 분명합니다. shared_ptr
을 보겠습니다. 이 스마트 포인터 모델 공유 소유권. 여러 엔터티가 동시에 포인터의 소유권을 주장 할 수 있습니다. 포인터는 모두이 끝나면 삭제됩니다. 따라서 3 개의 개체에 모두 동일한 개체에 shared_ptr
이 포함되어있는 경우 해당 개체는 shared_ptr
이 포함 된 세 개의 개체가 모두 삭제 될 때까지 삭제되지 않습니다.
shared_ptr
은 스마트 포인터라는 것을 이해하는 것이 중요합니다. 그러므로, 그것은 규칙 # 1의 적용을 받는다.
그건 의미가 없을 수도 있습니다. 결국 공유 소유권을 허용해야합니다. 이것이 허용 가능하다는 것을 의미합니다, 맞죠?
shared_ptr<int> p1 = new int(4);
shared_ptr<int> p2 = p1.get();
아니요. 이것은 여전히 잘못된 것입니다. auto_ptr
과 shared_ptr
사이의 차이점은 shared_ptr
이 할 수 있다는 것입니다 :
shared_ptr<int> p1 = new int(4);
shared_ptr<int> p2 = p1;
p1
에서 p2
의 사본 건설 있다고. 알몸 포인터에서 shared_ptr
을 생성하고 이미 존재하는 shared_ptr
에서 하나를 만드는 것의 근본적인 차이가 있습니다. 후자는 실제로 둘 사이의 소유권을 공유합니다. 전자는 단지 나쁜 일을 일으킬 것입니다.
따라서 알몸 포인터가 있고 shared_ptr
에 넣은 경우 해당 포인터 에 대해서만 한 번만 수행 할 수 있습니다. 소유권을 공유하려는 경우 소유권을 복사해야합니다.
하나의 세미 백도어가 있습니다 : enable_shared_from_this
. 이 유형에서 클래스를 파생 한 경우 클래스에는 클래스의 멤버 함수가 소유권을 이전하는 데 사용할 수있는 shared_from_this
개인 멤버가 있습니다.따라서 :
struct Type : public enable_shared_from_this
{
DoSomething()
{
shared_ptr<Type> p2 = shared_from_this();
FunctionThatTakesOwnership(p2);
}
};
shared_ptr<Type> p1 = new Type;
p1->DoSomething();
이외의 경우 명시 적으로 개체를 복사하여 소유권을 이전해야합니다.
감사합니다. 훌륭한 답변입니다. 나는 아직도 하나의 질문을 가지고있다. stl 컨테이너가 (insert, push_back 등 ...) 복사 생성자로 계산을 추가합니까? (어느 쪽이 맞습니까? – Yotam
@ Yotam : 예, 매개 변수를 복사합니다. 'shared_ptr'의 컨테이너를 가지는 것이 안전합니다. –