2011-11-20 3 views
6

std::vector<boost::shared_ptr<resource> >을 내부적으로 유지하는 클래스가 있습니다. resource_managerresource의 친구 클래스입니다. resource을 생성/삭제하려는 사람은 resource_manager입니다. 따라서 생성자를 비공개로 설정 했으므로 (확인이 가능함)shared_ptr에서 개인 소멸자를 호출하려면 어떻게해야합니까?

그러나 소멸자를 비공개로 설정하면 소멸자가 boost::shared_ptr에 의해 호출되므로 코드가 컴파일되지 않습니다. 이는 resource의 친구가 아닙니다. 나는 resource_manager에서 const resource* 만 리턴함으로써 클라이언트에 의해 삭제하지 않는 규칙을 시행 할 생각이지만, 어떻게 든이 메소드가 제공하는 보안에 만족하지 못합니다 (클라이언트가 어떻게 든 non-const에 대한 포인터를 통해 발생한다면 어떻게 될까요?)

shared_ptr을 사용하지 않는 명백한 해결책 외에도 어떤 문제 해결 방법이나 더 나은 해결책이 있습니까?

+0

수있는 유일한 방법 "클라이언트가 어떻게 든 const가 아닌 포인터에 걸쳐 발생"그들이 할 수있는 : 그래서 그냥 차례로 클래스의 friend 인 Deleter가 펑터 또는 (당신까지) 함수를 만들 const_cast를 사용하여 캐스트합니다. "보안"관점에서 원시 포인터와 shared_ptr 간에는 차이가 없으며, 차이점은 평생 관리에 있으며, shared_ptr없이 처리하는 방법이 확실하지 않습니다. – ronag

+4

'const resource *'는 삭제할 수 없다는 의미가 아닙니다. – UncleBens

+0

@UncleBens : 그렇지 않습니까? 나는 컴파일러가 const에 non-const 함수를 호출하는 것을 허용해서는 안된다고 생각했다. 나는 틀린가? 아니면이 규칙이 소멸자에게 적용되지 않습니까? –

답변

11

공유 포인터에 사용자 정의 deleter를 전달할 수 있습니다. 그 경우입니다

class Secret 
{ 
    ~Secret() { } 
    friend class SecretDeleter; 
    friend void SecretDelFunc(Secret *); 
}; 

class SecretDeleter 
{ 
public: 
    void operator()(Secret * p) { delete p; } 
}; 

void SecretDelFunc(Secret * p) { delete p; } 

std::shared_ptr<Secret> sp1(new Secret, SecretDeleter()); 
std::shared_ptr<Secret> sp2(new Secret, SecretDelFunc); 
+0

왜 똑같은 생각으로 나보다 항상 더 빠릅니까? 그만! : – Xeo

+0

@Xeo : 케이크의 다른 슬라이스를 선택하는 것이 더 좋습니다 - 나는'shared_ptr'에 내 눈을 단단히 고정 시켰습니다! ;-) –

+1

Btw, 당신은'SecretDeleter'를 인스턴스화해야합니다. – Xeo

1

아마도 shared_ptr<resource>을 친구로 신고 하시겠습니까? shared_ptr은 생성자를 호출하지 않으며 모든 클라이언트가 shared_ptrs를 삭제하기 전에 리소스 관리자가 포인터를 해제하는 경우에만 제거해야합니다. 이렇게하면 클라이언트가 보호 기능을 해제 할 수 없지만 클라이언트가 resource_manager의 "유언"에 대해 리소스를 보존 할 수 있습니다.

+0

시도했을 때 작동하지 않는 것 같음 –

관련 문제