2016-12-21 4 views
1

私はWidgetというクラスを持っています。このクラスは抽象クラスで、仮想メソッドがあります。オブジェクトのスライスを避けるために、すべてWidgetsは参照またはポインタとして格納されます。私はそれらに与えられたウィジェットを内部的に格納するコンストラクタを持ついくつかのクラスを持っています。したがって、格納されたWidgetは、コンストラクタの外で初期化されていなければならず、オブジェクトが存在する前に破棄することはできません。したがって、通常はWidgetが動的メモリを介して割り当てられます。私の質問は、この動的メモリをどのように扱うかに関するものです。私はオプションのリストを編集しました(他の人を自由に提案してください)。どちらが最も慣用的ですか?多型及びリソース管理に関するプログラム設計

1.スマートポインタ。スマートポインタは正しい選択肢のようですが、私はC++ 98を使用しているので、自分で書く必要があります。私もいつもsmart_pointer<Widget>と書いているのはちょっと醜いと思います。

2.保存時にWidgetsをコピーします。もう1つの方法は、元の代わりに渡されたWidgetのコピーを保存することです。これはオブジェクトのスライスを引き起こす可能性がありますが、わかりません。また、ユーザは、Widgetsが渡されたクラスを自分自身で書きたいと思うかもしれません。複雑すぎることは望ましくありません。

3.ユーザーがすべてを処理するようにします。おそらく、Widgetが時間通りに削除されることをユーザーに確認させることができます。これはQtのようなものです(?)。しかし、これはユーザのために物事を複雑にする。

+0

スマートポインタを使用します。欠陥があっても 'std :: auto_ptr'があります。 'std :: auto_ptr'がジョブを実行しない場合は、ジョブを書き込むか、すでに書き込まれているものを探します。 – Galik

+1

そして、 'typedef unique_pointer WidgetUPtr;'のようなものを使って、より冗長な入力をすることができます。 – Galik

+0

また、別のオプションは 'clone'イディオムです。 https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Virtual_Constructor。オブジェクトのスライスを避けるために*オプション2 *で使用できます。 –

答えて

1

私個人的には、このアプローチ(それは常に適用されていませんが、私が正常に複数回、それを使用)のような:

class WidgetOwner 
{ 
    vector<Widget*> m_data; 
public: 
    RegisterWidget(Widget *p) { m_data.push_back(p); } 
    ~WidgetOwner() { for (auto &p : m_data) delete p; } 
}; 

この単純なクラスは、単にポインタを格納します。このクラスはWidgetの任意の派生派生を格納できます。ただし、Widgetには仮想デストラクタがあります。多相クラスの場合、これは問題ではありません。

ウィジェットが登録されると、すべてが破棄されない限り破棄することはできません。

このアプローチの利点は、ポインタを自由に渡すことができることです。それらはすべて、ストレージが破壊されるまで有効です。これは手作りのプールの一種です。

+0

私はそれによって作成されていないものを削除することは悪い考えですか?この場合、ウィジェットを別のWidgetOwnerと安全に共有することはできません。 –

+0

まず第一に、これは完全なデザインではありません。これはもっとスケッチやパターンです。特定のニーズに合わせて調整する必要があります。次に、このクラスを「WidgetOwner」と呼びます。所有権がクラスに渡されることは明らかです。このパターンでは所有者は1人だけです。他のすべてのデザインパターンと同様に、すべてのユースケースを絶対にカバーしていません。 –

+0

面白いアイデア...すべてのウィジェットが動的に(妥当な)割り当てられていると仮定した場合、自分自身を登録させることができます。また、何らかの理由で私がプログラムが終了する前にウィジェットを解放できると判断した場合は、ウィジェットのデストラクタで呼び出されたWidgetOwnerにメソッドForgetWidget()を追加して、2度削除されないようにすることができます。 – Anonymous1847

0

私はスマートなポインタが最良の選択だと思います。テンプレートが醜いと感じたら、typedef

1

これは最も慣用的ですか?

確かにCの++の次期バージョンは「進むべき道」であると判断し、それがスマートポインタであるものとなり、ほとんどの慣用(あなたは他にも、/見つけ例えばブースト上の実装を使用することができますインターネット上のものはインスピレーションのために簡単かもしれません)。

c++98(それは考慮すべき巨大な要因です)を使用しているため、あなたはその文脈のために慣用的なものを取り、それは人の土地はほとんどないので、あなたに最も魅力的なデザインです。

関連する問題