2016-11-20 4 views
2

RequestStreamer는 스트리밍 요청을 돕기를 원합니다. 아래에서 보는 것과 반대로이를 구현하는 더 좋은 방법이 있습니까?클래스 B의 멤버 인 클래스 A의 객체입니다. B는 A의 객체를 필요로합니다.

이러한 종류의 코드가 적합한 디자인 패턴은 무엇입니까? 그것은 주인의 패턴이나 도우미 패턴이 될 것입니까?

이 예제는 따라서 당신은 (개인 회원 데이터에 액세스) 클래스를 인스턴스화 할 수 없습니다 클래스 요청에 생성자 및 민간 소멸자를 선언하는 A와 B

사이의 관계
class Request { 
    RequestStreamer* streamer; 
    int contentLen; 

public: 
    Request() 
    { 
     contentLen = 0; 
     streamer = new RequestStreamer(this); 
    } 
    ~Request() 
    { 
     delete streamer; 
    } 
    int getContentLen() 
    { 
     return contentLen; 
    } 
    bool initialize() 
    { 
     // Code to update 'contentLen' by reading from source request object. 
     // <code> 
     if (streamer) streamer->initialize(); 
    } 
    bool sendReq() 
    { 
     streamer->streamReq(); 
    } 
    int getBytes (int nBytes) 
    { 
     // some code to read nBytes from the input source of this request object 
    } 
}; 

class RequestStreamer { 
    Request* req; 
    bool bEnabled; 
    int chunkSize; 

public: 
    RequestStreamer(Request* aobj) 
    { 
     chunkSize = 1024*1024; 
     req = aobj; 
    } 
    ~RequestStreamer() 
    { 
    } 
    bool initialize() 
    { 
     if (req && req->getContentLen() > chunkSize) 
      bEnabled = true; 
    } 
    bool streamReq() 
    { 
     if (!req) return false; 

     // Assume that there exists socket object implementation already 
     if (bEnabled) 
     { 
      while (req->getBytes(chunkSize) != -1) 
       socket->send(req->getBytes(chunkSize)); 
     } 
     else 
     { 
      socket->send(req->getBytes(req->getContentLen())); 
     } 
    } 
}; 
+4

* A와 B 사이의 관계를 나타내는 적절한 예가 없습니다. 불가능한 그들의 관계 종류에 적합한 구조. – Ryan

+0

관련없는 메모에서 메모리가 누출됩니다. – Rakete1111

+0

'A'와'B'가 실제 세계의 대상이라면 무엇을 대표할까요? 'A'는 자동차와 같고'B'는 엔진입니까? 그 그림을 그리기가 정말로 어렵고, 객체 이름이'A'와'B'처럼 매우 모호 할 때 이상적으로 구조화합니다. – PrimRock

답변

0

를 표시하는 데 도움이됩니다.

  • 또한 클래스 요청이 클래스 RequestStreamer에 대한 포인터를 포함하면해야 forward declare 클래스 RequestStreamer 있도록합니다.

  • 당신은 클래스 RequestStreamer contains 클래스 요청에 대한 포인터 때문에 견인 각 클래스가 서로에 대한 포인터를 가지고 만들 따라서 each class must be implemented before the other 당신은 불완전한 개체를 사용할 수 없습니다 때문입니다. 결과적으로 당신은 그런 식으로 그것을 해결할 수 없습니다.

  • 는 템플릿을 사용하는 것이 해결하기 위해 : 여기에 템플릿의 예입니다

    #include <iostream> 
    using namespace std; 
    
    template <class T> class A; 
    template <class T> class B; 
    
    template <class T> 
    class A 
    { 
        public: 
         A(); 
         ~A(); 
        private: 
         B<T>* ptrB; 
    }; 
    
    template <class T> 
    class B 
    { 
        public: 
         B(); 
         ~B(); 
        private: 
         A<T>* ptrA; 
    }; 
    
    template <class T> 
    B<T>::B() : ptrA(new A<T>) 
    {} 
    
    template <class T> 
    B<T>::~B() 
    { 
        delete ptrA; 
    } 
    
    template <class T> 
    A<T>::A() : ptrB(new B<T>){} 
    template <class T> 
    A<T>::~A() { delete ptrB;} 
    
    int main() 
    { 
        A<int> a; 
        B<char> b; 
    
        return 0; 
    } 
    
1

코드에 따르면 A는 또한 자체를 초기화하는 B의 객체를 필요로한다. 두 클래스 사이에 1 < -> 1의 연관이 있음을 의미합니다. 두 클래스가 서로 포인터를 필요로합니다 (클래스간에 강한 상관 관계가 있기 때문에 "B help A"가 아닙니다). 그러나 요청에서 RequestStreamer를 만들 수 있는지 확인하려면 해당 생성자를 private로 설정하고 Request를 friend 클래스로 만듭니다.

1

여기에 많은 패턴이 있지만 명확하지 않으며 클래스가 자신의 역할에 대해 혼란스러워하는 것 같습니다.

나는 클래스를 조금 쪼개고 전략 패턴을 사용했다. 그리고 전략/데이터를 요청 생성자 인수로 전달했다. 이 모든 것이 조금 더 좋아질 것입니다. (여기에는 여전히 많은 잠재적 인 정리가 있습니다. 그러나 우려의 의도와 분리가 더 명확하다고 생각합니다.)

// What I'm sending 
class IRequestContent { 
    virtual int getContentLen() = 0; 
    int getBytes (int nBytes) = 0; 
}; 

// How I'm sending it 
class IRequestStreamerStrategy { 
    virtual bool initialize(IRequestContent * content, IRequest * req) = 0; 
    virtual bool streamReq(IRequestContent * content) = 0; 
}; 

// The combination of what I'm sending and how I'm sending it 
class Request : public IRequest { 
    shared_ptr<IRequestStreamerStrategy> streamer; 
    shared_ptr<IRequestContent> content; 

public: 
    Request(
     shared_ptr<IRequestStreamerStrategy> streamer, 
     shared_ptr<IRequestContent> content 
    ) : streamer(streamer), content(content) 
    {} 

    bool initialize() { 
     streamer->initialize(content, this); 
    } 

    bool sendReq() { 
     return streamer->streamReq(content); 
    } 
}; 

class RequestStreamer : public IRequestStreamerStrategy { 

    bool bEnabled; 
    int chunkSize; 

public: 
    RequestStreamer() { chunkSize = 1024*1024; } 

    bool initialize(IRequestContent * content) { 
     if (content->getContentLen() > chunkSize) 
      bEnabled = true; 
    } 

    bool streamReq(IRequestContent * content) { 
     if (!req) return false; 

     // Assume that there exists socket object implementation already 
     if (bEnabled) { 
      while (content->getBytes(chunkSize) != -1) 
       socket->send(content->getBytes(chunkSize)); 
     } else { 
      socket->send(content->getBytes(content->getContentLen())); 
     } 
    } 
}; 
관련 문제