2012-09-04 2 views
1

요청 개체에 해당 응답 개체가 있습니다. Sender 객체는 요청을 한 다음 응답을 수신합니다. 하나의 보낸 사람/수신기 개체가 다른 요청을 보낼 수 있습니다. 모든 요청은 전역 대기열에 저장되고 처리 된 후 해당 응답이 모든 수신기 객체에 전송됩니다.요청 - 응답 시스템

+2

포인터가 공유되었거나 약합니까? –

답변

2

문제의 해결책은 여러 가지가 있습니다. 하나는 트랜시버가 모든 Request 객체에 파괴 사실을 알리는 것입니다. 이를 위해 Request 개체가 자신을 등록하는 데 사용하는 Transceiver::addRequest()과 같은 메서드가 필요합니다. Transceiver의 소멸자에서 당신은 Request의 모든 등록을 통보해야합니다. 예를 들어 :

class Transceiver 
{ 
    virtual ~Transceiver() 
    { 
     for (auto request : m_requests) 
      request->deleteTransceiver(this); 
    } 

    void addRequest(Request* r) 
    { 
     m_requests.push_back(r); 
    } 

    void removeRequest(Request* r) 
    { 
     m_requests.erase(std::remove(m_requests.begin(), m_requests.end(), r), 
         m_requests.end()); 
    } 

    std::vector<Request*> m_requests; 
}; 

class Request 
{ 
    virtual void deleteTransceiver(Transceiver* t) = 0; 
    virtual void notify() = 0; 
}; 

class RequestImpl : public Request 
{ 
    RequestImpl(Transceiver* t) 
     : m_target(t) 
    { 
     if (t) 
      t->addRequest(this); 
    } 

    ~RequestImpl() 
    { 
     if (m_target) 
      m_target->removeRequest(this); 
    } 

    virtual void deleteTransceiver(Transceiver* t) 
    { 
     if (m_target == t) 
      m_target = 0; 
    } 

    virtual void notify() 
    { 
     if (m_target) 
      m_target->process(ResponseType()); 
    } 

    Transceiver* m_target; 
}; 

두 번째 접근 방법은 물론 그것을 사용하고 같은 Transceiver 만큼의 파괴를 방지하는 것입니다. Request 클래스에 std::shared_ptr<Transceiver> m_target을 사용할 수 있습니다. 즉, 송수신기가 적어도 관련 요청만큼 오래 지속됩니다.

유연성을 좀 더 높이려면 std::weak_ptr<Transceiver> 가능성도 있습니다. 그러면 트랜시버는 요청이 아직 살아있을 때 파괴 될 수 있습니다. 그러나 std::weak_ptr<Transceiver>::lock()을 시도 할 때 이 실패하면 Transceiver이 (가) 죽었다는 것을 알게됩니다.

편집 :은 그것의 Transceiver 전에 파괴되는 경우 Request을 제거하는 방법을 추가했습니다.

+0

글쎄, 그건 쉽지. 감사! – catscradle