2011-11-06 3 views
2

문제에 대한 최상의 해결책을 선택하는 데 문제가 있습니다. 현재, 저는 첫 번째 C++ 프로젝트에서 일하고 있습니다. Qt BTW를 사용하고 있습니다.하지만 .NET 개발자이기 때문에 C++에 관해 저에게 약간의 것들이 있습니다. :). 여러분 모두 알고 있듯이, Java 나 .NET과 같은 가젯 수집 세계에서 가장 좋은 방법은 느슨한 커플 링 클래스에 의존성 삽입을 사용하여보다 테스트 가능하고 유지 보수가 잘되도록하는 것입니다.하지만 C++에서 무엇을해야할지 모르겠습니다. C++에는 GC가 없으므로 모든 메모리 할당에주의를 기울여야하므로 너무 많은 질문이 발생합니다. 생성자에서C++ 컴포지션 모범 사례

class Rule : public QObject 
{ 
public: 
    explicit Rule(QObject *parent = 0); 

    unsigned int id(); 
    void setId(unsigned int id); 

    Application* application(); 
    void setApplication(Application* application) 
    { 
     m_Application = application 
     m_Application->setParent(this); 
    } 

}; 

, 내가 응용 프로그램 인스턴스 변수에 NULL 지정 해요 :

예를 들어, 나는 "응용 프로그램"클래스에 멤버 필드 가리키는가있는 클래스 "규칙"이있다. setApplication에서이 값을 응용 프로그램의 부모로 지정합니다. Qt 덕분에 Rule (부모)이 파기되면 응용 프로그램 인스턴스가 자동으로 삭제됩니다. 이것은 좋은 접근 방법입니까? 응용 프로그램 * 대신 QSharedPointer와 같은 스마트 포인터를 사용하면 더 좋을까요? 당신의 경험은 무엇이며 단점은 무엇이며 가장 좋은 접근 방법은 무엇입니까? 기꺼이 조언을 듣겠습니다. 여기에도 또 다른 까다로운 부분이 있습니다. 팀의 다른 개발자에게 클래스를 제공하거나 라이브러리를 게시하면 어떻게 될까요?

Application app; 
app.setId(1); 
Rule rule; 
rule.setApplication(&app); //When rule will be destroyed, the program would crash because app is allocated on the stack. 

또는

Application *app = new Application(); 
app->setId(20); 
Rule *rule = new Rule(); 
rule->setApplication(app); 
Application *appToAnotherLocation = new Application(); 
rule->setApplication(appToAnotherLocation); // This wouldn't result in memory leak, because app is already child of rule, but if I didn't used Qt this would be a problem... probably :) 

지금 대해 스마트 포인터 : 개발자는 쉽게 뭔가를 쓸 수 있을까? 규칙을 사용할 때와하지 말아야 할 규칙이 있습니까? 나는 항상 포인터 대신 QSharedObject를 반환하는 IRepository 인터페이스를 가지고있다. 이것은 좋은 접근 방법입니까 아니면 과장입니까?

class IRepository 
{ 
public: 
    virtual bool save(Application & application) = 0; 
    virtual bool save(Rule & rule) = 0; 
    virtual bool save(History & history) = 0; 

    virtual bool remove(Application & application) = 0; 
    virtual bool remove(Rule & rule) = 0; 
    virtual bool remove(History & history) = 0; 

    virtual QSharedPointer<Application> getApplication(unsigned int id) = 0; 

    virtual QSharedPointer<Rule> getRule(unsigned int id) = 0; 
    virtual QList< QSharedPointer<Rule> > getRules(unsigned int applicationId) = 0; 

    virtual QSharedPointer<History> getHistory(unsigned int id) = 0; 
    virtual QList< QSharedPointer<History> > getHistories(unsigned int applicationId) = 0; 
    virtual QList< QSharedPointer<History> > getHistories(unsigned int applicationId, QDateTime dateFrom, QDateTime dateTo) = 0; 
}; 

감사합니다. 귀하의 도움을 많이 주시면 감사하겠습니다.

+0

예제에 포인터가 없습니다 (포인터의 선언에서'* '). btw Qt 응용 프로그램에는 자체 메모리 관리 기능이 있습니다. –

+1

일반적으로 스마트 포인터는 좋습니다. [RAII] (http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization)에 대한 설명을 참조하십시오. –

+1

스마트 포인터를 사용하여 소유권을 나타냅니다. 원시 포인터는 소유권이 다른 곳에서 관리된다는 의미입니다. delete 키워드는 거의 사용하지 않아야합니다. –

답변

1

주관적인 견해;

처음 : Chris가 말했듯이, 스마트 포인터는 메모리 누수에 대한 매우 좋은 대안입니다. 항상 사용 해보십시오.

두 번째 : 좋은 디자인 방식은 제작자에게만 포인터를 삭제하는 것입니다. 한 클래스는 포인터를 만들고 파괴합니다. 다른 클래스에서 포인터를 삭제하지 마십시오. 이렇게하면 더 명확하고 읽기 쉽고 유지 보수가 쉬운 코드를 사용할 수 있습니다.

예에서 규칙은 응용 프로그램 포인터를 삭제하지 않아야합니다. 디자인에 대해 생각해보십시오. 왜 규칙이 응용 프로그램 부모인지 이해할 수 없습니다. 나는 응용 프로그램이 많은 규칙을 가지고 작업 할 수 있다고 생각한다.

1

다른 언급처럼, 스마트 포인터를 사용하여 소유권을 표현하십시오. Qt를 사용할 때 Memory management in Qt?을 읽어야합니다.