2016-09-23 4 views
1

weak_ptr을 역 참조하면 포인터가 만료되었는지 자동으로 확인하지 않습니다. 왜 이런 방식으로 설계 되었습니까?weak_ptr - Dereferencing - 만료시 throw

약점을 expired()을 사용하여 확인하지 않고 안전하게 참조 해제하고 null 인 경우 예외를 throw하고 싶습니다.

이 방법이 좋은 방법이 될 수 있으며 올바른 방법은 무엇입니까? *-> 연산자를 오버로드하여이 검사를 먼저 수행해야합니까? 무료 함수를 작성해야합니까? 같은

뭔가 : 다음

template< typename T > 
weak_ptr<T> & check(weak_ptr<T> & p) 
{ 
    if(p.expired()) 
     throw logic_error("Trying to dereference a null pointer."); 
    return p; 
} 

그리고 :

weak_ptr<int> pi; 
int i = *check(pi); 

감사합니다.

+2

을하지만 ... 당신이 할 수없는 약한 포인터 역 참조 . 당신은 그것을 잠그고 그것을 공유하고 그것을 사용해야합니다. – skypjack

+0

경쟁 조건을 피하기 위해 원시 포인터에 액세스하기 전에 shared_ptr을 변환/생성해야합니다. –

답변

6

expired()을 사용하면 멀티 스레드 프로그램에서 레이스가 도입되므로 유용하지 않습니다. 또한 weak_ptr이 만료 된 것이 예외적이지 않기 때문에 예외는 좋지 않습니다.

weak_ptr의 멋진 트릭은 역 참조가되지 않는다는 것입니다. 대신 객체에 액세스하려면 lock()을 호출하여 객체를 가리키는 shared_ptr을 원자 적으로 반환하거나 사용할 수없는 경우 null을 반환합니다.

약한 포인터를 액세스하는 일반적인 방법은 다음과 같습니다 당신이 정말로 예외를 원하는 경우

void safe_do(weak_ptr<T> &w) 
{ 
    shared_ptr<T> p = w.lock(); 
    if (p) 
     p->do(); 
} 

,이 변형 사용할 수 있습니다

void safe_do2(weak_ptr<T> &w) 
{ 
    shared_ptr<T>(w)->do(); //throws a bad_weak_ptr if w expired 
} 
+0

답변 해 주셔서 감사합니다. 그래서 당신이 올바르게 썼다는 것을 이해한다면 weak_ptr가 만료되면 dereferenced 될 수있는 shared_ptr로 weak_ptr을 변환하려고하는 단순한 사실이 발생할 것입니다. 이 경우 추가 점검을 할 필요가 없습니다. – Virus721

+0

@ Virus721 아니요. 그러면 테스트 할 수있는 NULL shared_ptr이 생성됩니다. –

+0

@RichardCritten 감사합니다. 그래서 내가해야 할 일은 lock()에 의해 주어진 shared_ptr을 취하는 함수를 작성하고, 이것이 null이면 예외를 던집니다. 그런 다음이 동일한 shared_ptr을 반환합니다. 그러면 안전하게 역 참조 해제 될 수 있습니다. 맞습니까? 편집 그래, 기본적으로 safe_do 메서드가 확인 된 shared_ptr을 반환하는 대신 호출을 수행한다는 점을 제외하고는 대답이 나온다. 죄송합니다. – Virus721

관련 문제