2016-10-21 2 views
0

클래스 A와 클래스 B를 놓습니다. 클래스 A의 각 인스턴스는 클래스 B의 0에서 N 개의 인스턴스까지 소유합니다. A 인스턴스가 삭제되면 B 인스턴스도 삭제됩니다 . 예를 들어다른 스마트 포인터를 사용하지 않고 weak_ptr 만들기

보기 : shared_ptr<parent>을 가진

class parent 
{ 
private: 

    vector< unique_ptr<child> > m_children; 

public: 

    weak_ptr<child> create_child() 
    { 
     m_children.push_back(move(make_unique<child>(???))); 
     return m_children.back(); 
    } 
}; 

class child 
{ 
private: 

    weak_ptr<parent> m_parent; 

public: 

    child(weak_ptr<parent> parent) : m_parent(parent) { } 
}; 

하나는 수는 수동으로 포인터를 사용하여 child를 만들었습니다. 그러나 클래스 parent의 범위 내에서 thisshared_ptr에서 this이 아니기 때문에 parent 인스턴스가 저장되어 있다는 것을 알지 못하므로 shared_ptr에서 weak_ptr을 만들 수 없습니다. 있다.

제 질문은 : child 클래스 범위 내에서 parent 인스턴스를 사용하기 전에 인스턴스가 해제되었는지 어떻게 확인할 수 있습니까? child을 만들 때 어떻게 "안전한"포인터를 반환 할 수 있습니까? 고맙습니다.

+3

'shared_ptr'에서만 'unique_ptr'에서 'weak_ptr'을 얻을 수 없습니다. –

+2

아마''std :: enable_shared_from_this' (http://en.cppreference.com/w/cpp/memory/enable_shared_from_this)를 찾고있을 것입니다. – Quentin

+0

@Quentin 그게 내가 필요한 것 같아요,하지만 내가 읽은 것에 따르면 부모가 shared_ptr에 저장되어야합니다. 클래스의 사용자는 문서에 언급되어 있어도 잊지 못할 수도 있습니다. 왜냐하면 내가 그것을 이해하지 못하는 경우가 아니면, 내게는 안전하지 않기 때문에 안전하지 않기 때문입니다. – Virus721

답변

-1

코드에서 부모 개체는 모든 자식을 소유하고 부모의 소멸자가 호출 된 후에 부모 개체를 파괴합니다. 따라서 부모가 파기 된 (아마도 다른 스레드에서) 자식 메서드가 여전히 실행중인 경우 자식 인스턴스는 이미 유효하지 않으므로이 상황을 감지하기 위해 안전하지 않은 작업을 수행 할 수 없습니다.

부모 객체의 '조기 사망'을 방지하기 위해 , 당신은 그런 식으로, 스레드를 동기화하는 자식 클래스에 뮤텍스를 소개 할 수 있습니다

class child 
{ 
private: 
    std::mutex m_mutex; 
    bool m_stopflag = false; 
public: 
    void execute() { 
    std::unique_lock<std::mutex> lock (m_mutex); 
    while (!m_stopflag) { 
     //doing something   
    } 
    } 

    ~child() { 
    m_stopflag = true; 
    m_mutex.lock(); 
    m_mutex.unlock(); 
    } 
} 

그러나 당신의 문제에 대한 내 생각이 잘못 인 경우 그리고 당신의 질문은 실제로 스레드를 멈추는 것이 아니라 이미 파괴 된 '자식'객체의 메소드 호출에 대한 보호를 얻는 것이 었습니다. 그러면 아마도 아무 것도 제안 될 수 없습니다. C++ 런타임은 그렇게 할 수 없습니다.

관련 문제