2011-11-06 9 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); 
    } 

}; 

を、Iは、アプリケーションインスタンス変数に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

主観的意見;

最初は:スマートポインタは、メモリリークのための非常に良い選択肢です。常にそれらを使用するようにしてください。

第2の:優れた設計アプローチは、クリエイターでのみポインタを削除することです。つまり、あるクラスがポインタを作成して破棄します。別のクラスのポインタを削除しないでください。これにより、より明確で読みやすく維持しやすいコードを持つことができます。

例では、ルールはアプリケーションポインタを削除してはなりません。あなたのデザインについて考えてみましょう:ルールがアプリケーションの親である理由を理解できません。私はアプリケーションが多くのルールで動作するかもしれないと思います。

関連する問題