2010-11-23 15 views
2

私は細胞の2次元マトリックスを持っています。通常、目に見えないアルゴリズムだけがこれらのセルで動作します。 Iは、セルセットのオプションの要素はRAIIを中断しますか?はいの場合、より良いアプローチは何ですか?

class Cell 
{ 
    ... 
    QAbstractGraphicsItem* representation_; 
    ... 
} 

コンストラクタは0行列に時々別の可視化クラス反復にrepresentation_グラフィカルオブジェクトへのポインタを追加し、コンテンツを視覚化細胞に要素を追加して、時には私は、各セルを視覚化します色ごとに各セルの

これはRAIIパラダイムを破ると思います。より良いアプローチがありますか?

私は別の2次元マトリックスを作成してそこから元のマトリックスにリンクすることができます。そのため、ポインターは視覚化側にありますが、2つのマトリックスが必要になります。

+0

ここでRAIIのどの部分が壊れていると思われますか? –

+0

representation_メンバーはほとんどの場合0であり、初期化されません。 – problemofficer

+1

これは、RAIIのパラダイムよりもMVCのパラダイムを壊すと思います。 – filipe

答えて

5

RAIIは、スコットマイヤーズが指摘するように、誤って名前が付けられています。

「Resource Acquisition is Initialization」と呼ぶべきではありません。「Destruction is Resource Release」と呼ばれるべきです。しかし、私たちはどこにいるのですか?

セルがrepresentation_が指し示すオブジェクトを所有し、そのデストラクタで削除した場合、これはヌルポインタでshared_ptrを初期化してから後で設定できるのと同じ方法でRAIIの形式ですそれは別のものに。私はあなたがそれを正しく使用すると仮定します(オブジェクトがいくつかのセルに保存されていることを確認した後、コンストラクタの完了とポインタの格納の間に最終的に解放される間に失敗することはありません)。もしそうなら、RAIIの重要な部分を使用しています。たとえそれが作業を行っているコンストラクタではありません。

これはおそらく単一責任の原則に違反していると思われます。 Cellをセルの代理にするようにしましたが、QAbstractGraphicsItemというオブジェクトをメモリ管理するためにのオブジェクトにする必要があります。おそらくrepresentation_をスマートポインタ型に変更することを単純化するので、Cellのデストラクタに特別なコードは必要ありません。

セルがrepresentation_が指し示すオブジェクトを「所有していない」場合、それは本質的にRAIIに違反するものではなく、実装していないだけです。他の何かがオブジェクトの所有権を担う必要があります。おそらく他のものがRAIIを使用しているかもしれません。 Cellが必要とする限り、オブジェクトの存続を保証するためには、Cellのライフサイクルに何らかの形で関与する必要があります(たとえば、セルを所有している場合は問題ありません)。そうでなければ、何とかRAIIに違反している可能性があります。

2

私はあなたがVisitor design patternを探していると思います。

+0

visitorパターンは、アイテムの数が限られていて、それらを描画/表現する方法が無制限の場合に適しています。古典的な訪問者は一方向の拡張性を追加しますが、一方の方向性から拡張性を削除します。 – CashCow

+0

ウィキペディアの記事を読んだ後、私の問題は複雑になると思います。 – problemofficer

+0

ええ、銀色の弾丸はありません... –

1

Cellやマトリックスアルゴリズムで必要とされない色情報を保持している可能性があります。それは非常に動的なアプローチです。

C++のような静的言語の通常のアプローチは、サブクラスCellです。あなたのアルゴリズムはCellSubclassの行列でうまくいくはずですが、要素を配列で値順に格納していたのでは少し問題が複雑になります。これを続けてアルゴリズムをテンプレート化したり、ポインタを配列に格納することができます。あなたが本当に拡張プロパティを使用する場合は

は、しかし、あなたが使用することができますmap<void*,IPropertyValue*>Cellを解放するときに拡張プロパティ値を漏洩しないようにIPropertyValueは、単に仮想デストラクタを提供Cell、内部。値を取得するときにキャストする必要があります。一意性と一貫性を保証するために、いくつかのプライベート静的変数のアドレスをキーとして使用します。

EDIT:1つのポインタだけを保存したい場合は、そのまま使用してください。ただし、スマートポインタを使用する場合は、swapを使用してください。そうすれば、すべてがRAIIになります。

+0

これはあまりにも複雑に思えます。より詳細な説明がありますか? – problemofficer

+0

2番目の段落は面白いです。ここでは複数の継承のための良いユースケースではありませんか?私は抽象クラス 'IVisualizable'と'クラスVisualizableCell:public Cell、public IVIsualizable'を意味します。あなたのアルゴリズムは 'Cell'sに作用し、あなたのビジュアライザーは' IVisualizable'に作用します。現在、ポインタでセルを格納していない場合は、Cellオブジェクトのサイズが不明なので、テンプレートアルゴリズムを使用する必要があります。 –

2

私は長いものがある場合、あなたの携帯のデストラクタが実際にQAbstractGraphicsItemオブジェクトを(そのデストラクタが仮想で、右?)を削除するように、あなたがすべてでRAII(リソース取得された初期化)を破壊しているとは思いません。ただし、このアーキテクチャでは、グラフィックアイテムとセルの間にの接続が存在する可能性が懸念されます。

はい、オブジェクトストアをプレゼンテーションから完全に分離するのは魅力的です。このための完璧なツール(Ben Voigtによって指摘されているように)は、クラスの外側から追加のデータ要素を使用してクラス定義を拡張できるものです。しかし、C++はこれをサポートしていません。視覚化ポインターの別のマトリックスを保持することをお勧めしますが、この2番目のデータ構造を維持する必要があります。これをしたくない場合は、この完全な分離を犠牲にして、実際的な単純さを図る必要があります。

いつでも1つの視覚化を有効にしていると仮定すると、ビジュアライゼーションシステムで使用するためにセル内に1つのポインタを保持することに問題はありません。あなたのコードはそのままです。はい、あなたはデータストレージとプレゼンテーションを結びつけていますが、非常に緩やかなリンクです。レイヤーが存在し、一部の(不透明な)セル固有のデータを保存することが必要な場合を除き、プレゼンテーションに関係するものはまだセルに依存しません。

visitorパターンは、ビジュアライザーを設計するのに便利ですが、それは直交する設計ポイントです。それらの訪問者がセルごとに余分なデータを保存する必要がある場合はどうなりますか?それが本当の質問です。マップでプロパティの拡張をシミュレートする場合は、複雑であり、複数のビジュアライゼーションが単一のマトリックス上で同時に動作している場合を除き、必要ではありません。

+0

ありがとうございました。私はあなたも受け入れたいと思いますが、あなただけを受け入れることができます。 – problemofficer

0

RAIIがブレークします。自己解放型ポインタを使用する必要があります。

+0

スマートポインタを意味しますか? – problemofficer

+0

@problemofficer:はい。 – Puppy

関連する問題