2

セルの 2 次元マトリックスがあります。通常、これらのセルでは目に見えないアルゴリズムのみが機能します。しかし、各セルを視覚化したい場合があるため、グラフィカル オブジェクトへのポインターを追加しました。

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

Cell のコンストラクターは、representation_ を 0 に設定します。場合によっては、別の Visualization クラスがマトリックスを反復処理し、各セルの内容を色で視覚化する要素を Cells に追加します。

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

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

4

5 に答える 5

5

(私が思うに) Scott Meyers が指摘しているように、RAII は間違った名前です。

「資源獲得=初期化」ではなく、「破壊=資源解放」と呼ぶべきです。しかし、私たちは今いる場所にいます。

Cell が が指すオブジェクトを「所有」しrepresentation_、そのデストラクタでそれを削除する場合、これは依然として RAII の形式でありshared_ptr、null ポインタで a を初期化し、後でそれを別のものに設定するのと同じ方法です。正しく使用していると仮定します(オブジェクトが作成された直後にセルまたは他のオブジェクトに保存され、コンストラクターの完了と最終的に解放される場所へのポインターの格納の間に失敗する可能性がないことを確認してください)。もしそうなら、作業を行うコンストラクターではなくても、RAII の重要な部分を使用していることになります。

単一責任の原則に違反している可能性があります。Cell は、セルを表現し、このオブジェクトのメモリ管理も担当します。QAbstractGraphicsItemおそらくrepresentation_、スマート ポインター型に変更すると簡単になるため、Cell のデストラクタに特別なコードは必要ありません。

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

于 2010-11-23T16:09:09.317 に答える
2

ビジターデザインパターンをお探しだと思います。

于 2010-11-23T14:33:41.480 に答える
2

Cellデストラクタが実際にQAbstractGraphicsItemオブジェクトを削除する限り(そのデストラクタは仮想ですよね?)、RAII (Resource Acquisition Is Initialization)を壊しているとは思いません。ただし、このアーキテクチャでグラフィックアイテムとセルが結合する可能性について懸念しているようです。

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

いつでも 1 つのビジュアライゼーションのみをアクティブにしていると仮定すると、ビジュアライゼーション システムで使用するためにセル内に 1 つのポインターを保持しても問題はないと思います。あなたのコードはそのままで問題ありません。はい、データ ストレージとプレゼンテーションを結び付けていますが、かなり緩いリンクです。セルは、レイヤーが存在し、いくつかの (不透明な) セル固有のデータを格納する必要があることを認識することを除いて、プレゼンテーションに関連するものにはまだ依存していません。

他の提案に対処するために、訪問者パターンはビジュアライザーの設計に役立ちますが、それは直交する設計ポイントです。これらの訪問者がセルごとに余分なデータを保存する必要がある場合はどうすればよいでしょうか? それが本当の質問です。マップを使用してプロパティ拡張をシミュレートするのは複雑であり、1 つのマトリックスで複数の視覚化を同時に実行する場合を除き、必要ありません。

于 2010-11-23T15:28:36.340 に答える
1

拡張プロパティが必要なようです。おそらく、Cellまたはマトリックスアルゴリズムで必要とされない色情報を保持しています。これは非常に動的な言語アプローチです。

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

ただし、拡張プロパティが本当に必要な場合は、map<void*,IPropertyValue*>insideCellを使用できますIPropertyValue。これは、仮想デストラクタを提供するだけなので、を解放するときに拡張プロパティの値がリークすることはありませんCell。値を取得するときにキャストする必要があります。一意性と均一性を保証するために、いくつかのプライベート静的変数のアドレスをキーとして使用します。

編集:ポインタを1つだけ保存する必要がある場合は、現在の方法でうまく機能します。ただし、スマートポインターを使用swapし、割り当てるときに使用します。そうすれば、すべてがRAIIになります。

于 2010-11-23T14:45:59.590 に答える
0

これは RAII を壊します。自己解放ポインターを使用する必要があります。

于 2010-11-23T15:31:01.170 に答える