8

「どうやってやるか」ではなく、「どうやって正しくやるか」が問題

さまざまなウィジェットが子とその (メンバー) 変数を表示する Qt でエディターを開発しています。これらの各ウィジェットは、編集された子への参照/ポインターを保持して、メンバー変数を表示および変更する必要があります。

最初の試みは、私が学んだ古い ANSI C の方法でした (そして、まだ少し行き詰まっています) 使用されたオブジェクトへの単純な生のポインターを使用します。それは正常に動作しますが、C++ 11 標準はスマート ポインターをサポートしており、それらの使用が推奨されているため、それらを使用しようとしています。

問題は、この場合にそれらを使用する「最良の方法」が何であるかがよくわからないことです...スマートポインターを読んだ後:または、あなたの赤ちゃんを所有しているのは誰ですか?いつどの種類のポインターを使用しますか? 他のいくつかは、異なる結論に達しました。

*unique_ptr編集されたオブジェクトは明らかにその子を作成および削除する所有者であるため、最初の方法は a を使用することです。ウィジェットは、それらを表示または変更するために単に子を参照しています。問題は、ウィジェットが子をどのように参照するかです...

今のところ、get()メソッドで取得した生のポインターをまだ使用しているだけですunique_ptrが、これにはちょっと欠陥があるようです。ポインターで誤って削除を呼び出して、スマート ポインターの利点をキャンセルすることはまだあります。

2 番目のアプローチは、shared_ptr多くのオブジェクトが子を参照して編集するため、a を使用することです。また、1 つのウィジェットでそれを誤って削除しても、他のオブジェクトがまだ所有しているため、害はありません。問題は、彼らがそれを所有していることです。編集したオブジェクトから削除したい場合は、実際に削除する前に、すべてのウィジェットに削除するよう通知する必要があります。(これもまた欠陥があり、エラーが発生しやすいようです)

私は両方の方法に満足していません。unique_ptrオブジェクトの子を指すよりクリーンな方法はありますか? または、この問題に対する完全に異なるより良いアプローチが欠けていますか?

4

4 に答える 4

2

生ポインタの代わりにとのshared_ptr代わりにa を使用したいとします。これにより、まさにあなたが求めているものが得られます。は、基になるオブジェクトを削除する編集済みオブジェクトの機能を妨げません。unique_ptrweak_ptrweak_ptr

于 2013-08-27T01:51:40.523 に答える
1

Qt を使用している場合は、std:: スマート ポインターの代わりに Qt スマート ポインターを使用することを検討してください。

またはQObjectの場合:

  • QPointer(またはQWeakPointer、Qt4のesp)

または、コピー オン ライト データ共有、Qt コンテナー、および QString スタイルを実現するには:

他のポインター クラスもありますが、上記のいくつかは、あなたが望むことを行う可能性が最も高いものです。また、Qt コンテナー クラスQStringsなどにデータがある場合、それらはコピー オン ライト セマンティクスを使用して独自のメモリを処理し、通常はポインターではなくプレーンな値 (場合によっては参照) として渡される必要があります。

しかし、最も重要なのは、親を持つ QObjects でstd::unique_ptrorを使用しないことです。なぜなら、親が最初に子を削除すると、std:: ポインターが再び子を削除し、プログラムをクラッシュさせるからです (他の方法でも問題なく動作し、子は親にそのことを通知します)。std::shared_ptr削除されています)。つまり、QObjects と std:: ポインターを混在させると、微妙なバグが発生する可能性が高いので、そうしないでください。念のためと言って、あなたがそれを行っているかどうかはあなたの質問からは明らかではありません。

于 2013-08-27T06:13:36.990 に答える