2017-02-22 5 views
4

通常Qtでdeleteの代わりにdeleteLater()を使用することをお勧めします。しかし、それはオブジェクトをぶら下げてしまうという問題を引き起こします。削除対象としてマークされていますが、Qt APIが返す子リストにはまだ表示されています。 (この動作は非常に直観的ではないので、私の急速に発展しているQt quirks senseは私にそれを検証させました。)それで、そのようなオブジェクトを追跡する慣用方法はありますか?私は、もちろん、後で削除する予定のオブジェクトを追跡するには?

class DeleteLaterable 
{ 
public: 
    void markForDeletion() { mMarked = true; } 
    bool isMarked() const { return mMarked; } 
private: 
    bool mMarked = false; 
}; 

のようなアドホック・ソリューションを使用して、公にそれからすべてを継承するが、それは仮想継承ワームの全体の異なる缶を開くことができます。どんな良いアイデアですか?

+4

子を削除し、次に 'deleteLater()'を削除します。 – dtech

+2

オブジェクトの削除のスケジューリングでsetParent(nullptr)を呼び出すだけで動作しますか? –

+0

ありがとう、みんな。手で関連するリストからそれを選ぶことになります。 – sigil

答えて

2

Qt 5.8以降、削除予定のオブジェクトをボックスから追跡する方法はありません。

deleteLater()を呼び出すと、対象オブジェクトにイベント(QDeferredDeleteEvent)をポストするだけです。保留中のイベントのリストを取得する方法がないため、どのオブジェクトがQDeferredDeleteEventを受け取るかを知ることはできません。あなたはいくつかのソリューションがあります欲しいものを達成するために

  1. (deletelaterを呼び出す)とオブジェクトを追跡します「DeleteObjectの(QObjectを*)」機能と「DeleteLaterManager」 クラスを使用します削除されるまで
  2. QAbstractEventDispatcherを再実装し、QEvent::DeferredDeleteのイベントを追跡します。
  3. タイプQEvent::DeferredDeleteのカスタムイベントクラスを使用し、deleteLater()を呼び出す代わりにQCoreApplication::postEvent()を呼び出します。

子リストに表示されているオブジェクトのみに関心がある場合は、deleteLater()を呼び出すときに親を削除するだけで済みます。

「この動作は真剣に直観に反する」のはなぜですか? deleteLater()のドキュメントでは、オブジェクトの削除がスケジュールされると記載されていますが、なぜ親子関係に影響がありますか?

+0

@ Benjamin Tそれは、それが正常に動作する方法ではないので、直観に反します。たとえば、削除するファイルにマークを付けると、OS APIはそれを通常のファイルと一緒に一覧表示しません。ファイル自体は、いくつかのシステムレベルの手続きの後半で削除される可能性がありますが、最終的なものを除いて、すべて元の状態に戻すことができますが、ビジネスロジックの観点からファイルの存続期間は、「このものを削除する」フラグを設定すると終了します。 – sigil

+0

@sigilオブジェクトは削除のために「マークされていません」、削除のために「スケジュールされた」ものです。 「deleteLater」を呼び出すと、オブジェクトを変更しても、将来のある時点で自動的に削除されることが通知されます。一般的に言えば、APIが文書化されている以上のことを行うべきではないと考えてください。「deleteLater」は「markAsDeleted」ではなく、Qtドキュメントには「削除しようとしているオブジェクトはリストされていません。 –

関連する問題