2013-10-02 2 views
8

난 원시 포인터 멤버를 일부 스마트 포인터로 감싸서 개발 클래스 내에서 삭제되지 않도록하고 싶습니다. 포인터 아래 개체의 소유자가 클래스 외부에 있습니다. 따라서 boost::shared_ptrstd::auto_ptr처럼 보이지 않습니다. 다음은 축소 된 예입니다.raw 포인터에서 weak_ptr <> 만들기

class Foo { 
    boost::weak_ptr<Bar> m_bar; 
public: 
    void setBar(const Bar *bar) { // bar created on heap 
    m_bar = bar;    // naturally compilation error 
    } 
}; 

물론 컴파일 오류가 발생합니다. 원시 포인터 (있는 경우)에서 weak_ptr을 초기화하는 올바른 방법은 무엇입니까?

+0

가능한 중복을 할 수있다 전환] (http://stackoverflow.com/questions/17522020/shared-ptr-weak-ptr-conversions) –

+1

클래스 내에서 해당 포인터의 삭제를 방지하려면 해당 클래스에서'delete'를 호출하지 마십시오. 클라이언트에 대한 포인터를 노출하는 접근 자 함수를 제공하지 마십시오. 'weak_ptr'은'shared_ptr'에 의해 소유 된 객체의 비 소유 뷰를위한 것입니다. 그 포인터를 어떻게 든'weak_ptr'에 넣을 수 있다면, 포인터가 만료되었는지도 모르며, 클래스 내에서'delete m_bar.lock(). get();을 호출하지 못하게 할 수 없습니다. 결코 100 % 바보 같은 것을 만들 수는 없습니다. – Praetorian

답변

10

당신은 할 수 없습니다. 당신은 오직 shared_ptr 또는 다른 weak_ptr 중에서 weak_ptr을 생성 할 수 있습니다. 그래서 포인터의 소유자가 원시 포인터 대신 shared_ptr을 보유하고 모든 것이 잘되어야합니다.

1

원시 포인터 대신 공유 포인터를 전달하고 해당 공유 포인터에서 약 포인터를 생성하십시오. 이것은 포인터의 소유자가 클래스 외부에있는 경우 실제로는 유일한 방법입니다.

4

약 포인터의 목적은 원시 포인터가 삭제 된 경우 사용할 수 없게하는 것입니다. 그러나 미처리 포인터가있는 경우 약한 포인터는 삭제되었음을 알 수 없습니다. 대신 원시 포인터를 "소유"하는 shared_ptr이 있어야합니다. 그런 다음 shared_ptr을 참조하는 weak_ptr을 만들 수 있습니다.

shared_ptr이 범위를 벗어나 마지막 "강력한"스마트 포인터 인 경우 원시 포인터가 자동으로 삭제됩니다. 그런 다음 weak_ptr을 잠그려고하면 "강한"포인터가 남아 있지 않아 개체가 존재하지 않는다는 것을 알 수 있습니다. 당신이 말한

2

다 한 가지를 제외하고, 완벽하게 합리적인 것 같다 : 이것은 원시 포인터를 복용해서는 안

void setBar(const Bar *bar) 

. 이상적인 경우 weak_ptr을 가져야합니다. 또는 매력적인 인수가 있으면 shared_ptr 일 수 있습니다.

해당 객체의 실제 소유자는 weak_ptr을 구성해야하고 setBar을 호출해야합니다. 이렇게하면 소유권 의미가 유지됩니다. 당신이하는 일은 소유 객체가 미가공 포인터를 가지고 그것을 setBar으로 전달하는 것입니다. 이것은 객체의 소유권에 의미 적 차이를 만듭니다.

5

포인터를 소유 한 shared_ptr 또는 weak_ptr을 보유하는 것이 유일한 방법입니다. 그렇지 않으면 weak_ptr에 소유권을 공유하기 위해 기존 소유자를 찾을 방법이 없습니다.

이미 다른 shared_ptr 소유 한 원시 포인터에서 shared_ptr을 얻을 수있는 유일한 방법은 Barenable_shared_from_this<Bar>에서 파생 된 경우, 다음 [공유 \ _PTR & 약한 \의 _PTR의

m_bar = bar->shared_from_this();