2013-04-10 1 views
2

다중 스레드 응용 프로그램에서 자동 연결 관리로 부스트 신호 2를 사용하고 싶습니다. 내 클래스는 enable_shared_from_this<>에서 상속 받고 다른 멤버 메서드 내에서 멤버 메서드를 연결하려고합니다. 내 코드는 가능한 한 빨리해야한다, 그래서 연결이 자주 재건 될 수있다 (에도 불구하고 부스트 signals2 성능 자체) :enable_shared_from_this가 임베디드 weak_ptr에 직접 액세스 할 수없는 이유는 무엇입니까?

typedef boost::signals2::signal<void()> signal_type; 

struct Cat : public enable_shared_from_this<Cat> 
{ 
    void meow(); 

    void connect (signal_type& s) 
    { 
    // can't write this 
    s.connect (signal_type::slot_type (&Cat::meow, this, _1).track (weak_from_this())); 

    // ok, but slow?! two temporary smart pointers 
    weak_ptr<Cat> const myself (shared_from_this()); 
    s.connect (signal_type::slot_type (&Cat::meow, this, _1).track (myself)); 
    } 

    // i am missing something like this in the base class 
    // protected: 
    // weak_ptr<Cat> const& weak_from_this(); 
}; 

내 설계 목표는 충돌 할 수 있음을 알고 (자동 연결 관리 및 스레드 안전뿐만 아니라 어쨌든 빠른 코드) 만 :

  1. 이유에 enable_shared_from_this<> 부족 직접 액세스가 포함 된 않습니다 weak_ptr<>? 나는 반대의 이유를 볼 수 없습니다. 내 비슷한 유스 케이스가 없습니까?

  2. 위의 해결 방법보다 빠른 해결 방법이 있습니까?

편집 :

나는이 같은 somethink을 할 수있어,하지만 난 추가 스토리지/초기화 검사 처벌 피하려고 : 아니오 있기 때문에

template <typename T> 
struct enable_weak_from_this : public enable_shared_from_this<T> 
{ 
protected: 
    weak_ptr<T> /* const& */ weak_from_this() 
    { 
    if (mWeakFromThis.expired()) 
    { 
     mWeakFromThis = this->shared_from_this(); 
    } 

    return mWeakFromThis; 
    } 

private: 
    weak_ptr<T> mWeakFromThis; 
}; 
+0

"느린"사람은 누구입니까? 그것에 대해 "느린"무엇입니까? –

+0

2 개의 임시 스마트 포인터 인스턴스가 필요합니다.이 인스턴스는 이미 존재하는 weak_ptr을 생성하기 위해 적어도 4 개의 불필요한 연동 연산을 발생시킵니다. – eel76

+0

첫째, * * "이미 존재하지 않습니다"; 내 대답을 보라. 둘째로, 그렇게 느리게는되지 않습니다. 이 문제가 있음을 나타내는 프로파일 링 데이터가 있습니까? –

답변

2

weak_ptr에 액세스 할 수없는 이유는 enable_shared_from_this입니다. 을 사용해야합니다. weak_ptr을 가지면 이 가능하고 구현이 enable_shared_from_this 일 수 있습니다. 그것은 유일한 것이 아닙니다.

enable_shared_from_thisshared_ptr과 동일한 표준 라이브러리의 일부이기 때문에 weak_ptr을 직접 저장하는 것보다 효율적인 구현을 사용할 수 있습니다. 그리고위원회는 그러한 최적화를 막고 싶지 않습니다. // 좋아,하지만 느린

! 하나의 일시적인 스마트 포인터의 두 일시적인 스마트 포인터

. elision/movement 복사는 첫 번째 객체 이외의 것을 처리해야합니다.

+0

표준에서 실제 구현을 정의하거나 제한하지 않는다는 것을 알고 있습니다. 그러나 표준이 shared_from_this()를 제공하면 실제 구현을 제한하지 않고 weak_from_this()를 제공 할 수도 있습니다. 내부적으로 weak_ptr을 사용하는 구현은 weak_from_this()의 빠른 구현을 제공 할 수 있습니다. – eel76

+0

복사 elion이 실제로 여기에서 작동합니까? 우리는 weak_ptr => shared_ptr => weak_ptr이면서 weak_ptr => weak_ptr => weak_ptr이 아닙니다. – eel76

+0

@ user2266052 : "두 개의 임시 스마트 포인터"가 있다고하셨습니다. WP-> SP-> WP는 * 임시 * SP만을 사용합니다 (WP-> WP, 당신은 여전히 ​​그것을 복사해야합니다). 그래서 나는 두 번째가'weak_ptr'의 생성자 또는 무엇인가에 대한 매개 변수라고 가정했다. –

-1

그것은 일 수 있습니다을 shared_ptrCat 인스턴스를 참조합니다. weak_ptr에는 하나 이상의 활성화 된 shared_ptr이 필요합니다. connect 방법에 먼저 shared_ptr 구성원으로 변수를 배치하고이를 할당

보십시오 : 더 shared_ptr이없는 경우

typedef boost::signals2::signal<void()> signal_type; 

struct Cat : public enable_shared_from_this<Cat> 
{ 
    void meow(); 
    boost::shared_ptr<Cat> test; 

    void connect (signal_type& s) 
    { 
    test = shared_from_this(); 
    s.connect (signal_type::slot_type (&Cat::meow, this, _1).track (weak_from_this())); 
    } 
}; 

그러나 기본적으로, 아니 weak_ptr을있을 수 없다. weak_ptr이 아직 사용되고있는 동안에 모두 shared_ptr이 사라지는 경우 weak_ptr은 존재하지 않는 개체를 가리킬 수 있습니다.

주 : 개체가 해제되지 않을하는 원인이됩니다 내 시험 생산 코드에서 사용할 수 없습니다.

+0

당신은 내 질문에 대해 오해하고있다. cat 객체의 수명을 관리하는 shared_ptr 인스턴스가 있습니다. 나는 내 코드 작업을하는 데 문제가 없지만 빨리 처리 할 수있다. – eel76

관련 문제