2016-10-31 14 views
3

개체에 개체가있을 때 개체의 수명을 고려해야하는 composition을 사용합니다. 동일한 상황 일 때 unique_ptr을 사용하지만 객체는 nullptr 일 수 있습니다."가장 짧은"유형의 수명을 관리하는 방법은 무엇입니까?

우리는 외부 개체가 우리 개체를 필요로 할 때 shared_ptr을 사용합니다. 따라서 마지막 외부 개체가 관심을 잃을 때까지 수명이 연장됩니다.

여기 평생 다른 상황에 대해 물어보고 싶습니다. 개체가 살아야 할 경우 가장 짧은 시간이입니까?

다음은 예입니다. 펑터를 저장하고 계산이 완료된 후 실행합니다. 현재

1. fulfilling its task - therefore it should be able to destroy istelf 

or 

2. the parent loosing interest in the timer - so the parent should be able to 
    destroy the object as well 

, 나는 독특한 포인터 어색한 구현을 사용 : 그것은이 타이머 객체가 이후에 파괴되는 것을, * 나에게 의미가 있습니다. 이 문제의 좋은 패턴/가이드 라인/구현은 무엇이 될까요?

* 이유 : 1) 펑 터는 다른 자원 2) 타이머가 매우 큰 숫자로 설정 한 다음 부모가 파괴 된 경우, 우리는 일반적으로 '돈) 3 포기 수 있었다 소유 할 수 그 콜백을 호출하고 싶지 않다.

+0

이것은 네트워크 요청에 응답하여 무언가를 계산할 때 스레드 취소와 공통점이 있지만 연결이 갑자기 종료되었습니다. 컴퓨팅을 완료해도 부패는 발생하지 않지만 자원 낭비입니다. – curiousguy

답변

0

나는 최선의 해결책은 실제 타이머 객체에 대한 유일한 포인터를 가진 래퍼 객체를 갖고, 그것이 파괴 되었다면 null을 반환하는 타이머 객체에 대한 getter를 갖는 것이라고 생각한다.

그런 식으로 타이머가 만료되고 소멸되는 경우, 관심을 잃지 않은 호출자는 타이머 개체에 대해 실제로는 유효하지만 실제로 유효하지 않은 포인터를 보유하지 않습니다.

2

여기에는 심각한 동시성과 재진입 문제가 있습니다.

두 개 이상의 코드 비트가 포인터를 삭제할 권한이있는 경우 두 코드 모두 해당 포인터를 비 참조 할 수 없으므로 다른 코드는 포인터를 삭제할 수 있습니다.

마찬가지로, 소유권이 있는지 확인하는 모든 분기는 동시성이 없더라도 다른 비 로컬 (함수 호출)이 실행되는 순간 부실해 질 수 있습니다.

우리는이 문제를 해결할 수 있습니다.

template<class T> 
struct shared_destroyable { 
    std::shared_ptr<T> lock() const { 
    return atomic_load<T>(ptr.get()); 
    } 
    explicit operator bool() const { return (bool)lock; } 
    void reset(std::shared_ptr<T> pin = {}) { 
    atomic_store(ptr.get(), std::move(pin)); 
    } 
    shared_destroyable(std::shared_ptr<T> pin): 
    ptr(std::make_shared<std::shared_ptr<T>>(std::move(pin)) 
    {} 
    shared_destroyable()=default; 
    shared_destroyable(shared_destroyable&&)=default; 
    shared_destroyable(shared_destroyable const&)=default; 
    shared_destroyable& operator=(shared_destroyable&&)=default; 
    shared_destroyable& operator=(shared_destroyable const&)=default; 
private: 
    std::shared_ptr<std::shared_ptr<T>> ptr; 
}; 

이것은 weak_ptrshared_ptr 하이브리드와 같은 모호한 동작합니다.

마지막 개체가 사라지면 개체가 삭제됩니다.

그러나, 그들 .reset()의 경우, 객체는 즉시 lock() 에드을 가지고 마지막 다른 코드는 그 범위을 종료되었습니다 을 파괴한다.

언급 된 변경 사항을 참조하십시오.

if(auto sp = sd.lock()) { 
    // use sp 
} 

을하고 sp 수명은 누군가가 다른 스레드에서, 블록 내에서 sd.reset() 않는 경우에도 {}의 범위를 마지막으로 보장하거나 호출 할 때 :

그래서 사용에서이 작업을 수행 다른 방법.