qsharedpointerによって管理されるポインターの削除を防ぐ方法
-
08-10-2019 - |
質問
QTアプリケーションにいくつかの断続的なセグメンテーション障害があります。問題は私たちの(悪い)使用に関連していると思います QSharedPointer
. 。 QTドキュメントの状態 :
qsharedpointer :: qsharedpointer(t * ptr):ptrを指すqsharedpointerを作成します。ポインターPTRは、このqsharedpointerによって管理されます 別のqsharedpointerオブジェクトに渡さないでください また このオブジェクトの外で削除されました.
私たちは両方をやっていると思います そうでないでください... :/
ポインターが管理されていることを強制するOOPの方法はありますか QSharedPointer
削除したり、別のものに渡すことはできません QSharedPointer
?
最良の解決策は、コンパイラエラーがあることです。
解決
通常のパターンは、を置くことです new
このようなスマートポインターのコンストラクター内の声明:
QSharedPointer<Obj> p (new Obj(2));
そうすれば、裸のポインター自体への参照はありません。
すべての新しいオペレーターがこのようなラインにあるようにコードをリファクタリングすると、すべての問題が解決されます。
他のヒント
まあ、OOP風の方法は、ラッパークラスのプライベートメンバーとして生のポインターを作成し、共有ポインターに作用する方法を介してポインター上のアクションのみを実行することです。馬鹿げていますね。
または、生のポインターを使用してクラスを他のクラスのベースクラスにし、生のポインターをクラスのプライベートメンバーにすることもできます。この点で、あなたは多かれ少なかれ何もしない抽象的なクラスを作成しています。代わりに、デリバティブクラスはすべての作業を行う必要があり、生のポインターにアクセスできないため、コンピレーションは失敗します...これは誰かが共有ポインターから生のポインター値をコピーするのを止めません。
最終的に、あなたの最善のポリシーは、問題のすべての関数を変化させて共有ポインターまたは生のポインターを使用することだと思います。 1つの共有ポインターを安全に別のポインターにコピーできますが、なぜそのようにしないのですか?
編集:共有ポインターを使用しているかどうかに関係なく、所有権の問題があるように聞こえるかもしれません。ポインターが1つのスコープで作成された場合、渡された関数がない限り、そのスコープで削除する必要があります 契約上 ポインターの所有権を取得します。このシナリオで共有ポインターを使用すると、最終的には異なるバグのみが発生します。ポインターの共有よりも深い設計の問題があるようです。
私は共有ポインターの特定のQT実装に精通していませんが、一般的なガイドラインとして:生のポインターと管理されたポインターを混合しようとすると、通常、血液で終わります。動的に割り当てられたデータの所有権を取得する際の共有ポインター実装を「信頼」したら、いかなる状況でも自分でオブジェクトの寿命を管理しようとする必要はありません(たとえば、提供されたポインターを削除することで)。
QsharedPointerによって管理されたポインターを削除できないことを強制するOOPの方法はありますか?
尖ったタイプにプライベートデストラクタを持ち、qsharedpointerを友人として宣言する奇妙なテクニックを想像することができると思います(「外部削除」がコンパイルされるのを効果的に防止します)が、これから良いことは何でも出てくることができるとは思わないでしょう(そして、QsharedPointerに新しく転送されない限り、あなたのタイプが絶対に使用できないことに注意してください)。
QsharedPointerによって管理されたポインターを別のQSharedPointerに渡すことができないことを強制するOOPの方法はありますか?
私は考えられないので、それが生のポインターが所有権をQsharedpointerに転送したら、生のポインターの操作を避けるべきもう1つの理由です。
すべての.data()の使用についてコードを確認し、返品したものが保存されておらず、削除されていないことを確認してください。ハードコンパイラのエラーが良いとは思わない。なぜなら、パスポインターを保存したり削除したりしない関数に、生のポインターを渡すことができないからです。 (特にサードパーティのコードを使用する場合、すべてを常に変更して共有ポインターを使用することはできません。多くの場合、RAWと共有PTRとの両方で動作したいと思うことがよくあります)。 QSharedPointer :: data()を削除して(QTにパッチを当てて)マークして、コンパイル時間警告を取得することができます。