5

私のqt作業でスマートポインターの使用を開始することを考えています。スマートポインターがQtガベージコレクションとどのように連携するかを混乱させるものです。Qt 全体は、子 QObject が QObject* 親を ctor 引数として構築するイディオムに基づいているため、ガベージ コレクションが有効になります。例えば:

     QWidget* mWidget = new QWidget(this);//Here we not only 
                                          //ensure that mWidget will be deleted  
                                          //when its parent is deleted, but also tell qt,  
                                          //that mWidget is not a window, but belongs to 
                                          //parent's layout         

今、mWidget をスマート ポインターにラップしたい場合。

 typedef QScopedPointer<QWidget> WidgPtr;
 WidgPtr mWidget = WidgPtr(new QWidget(this));

しかし、親の dtor が呼び出されると、mWidget のポインターで delete が 2 回呼び出されます。1 つ目はガベージ コレクションによるもので、2 つ目はスマート ポインター dtor が呼び出されたときです。

もちろん、親なしで mWidget を構築し、いくつかのフラグを変更してウィンドウの動作をオフにするか、setParent() を呼び出すことができます (ただし、mWidget は 2 回削除されます)。しかし、生のポインターの代わりにスマートポインターを使用できるようにするために、このような複雑な初期化を行うのは多すぎます。それとも、何かが恋しいですか?ありがとう。

4

1 に答える 1

5

QScopedPointerターゲットオブジェクトが生きているか死んでQSharedPointerいるかを認識していないため、スマートポインターをメンバー変数以外の場所に保持すると、はい、デストラクタが2回呼び出される可能性があります。そのため、これらの種類のスマート ポインターはあまり適してQObjectsいません (ただし、オブジェクトに親がない場合でも便利です)。

への保護されたポインターを保持する必要がある場合はQObject、 を使用QPointerします。オブジェクトが破棄されると null になるためdelete、騒乱を引き起こすことを恐れずにいつでもそれを行うことができます。ただしQPointer、デストラクタで参照されているオブジェクトを破棄しないことに注意してください。ほとんどの場合、階層を構築QObjectsし、所有権システムにメモリをクリーンアップさせる必要があります。

于 2012-10-13T08:50:05.607 に答える