2013-05-21 7 views
13

私は新しいプロジェクトでC++ 11のスマートポインタを使用したいが、問題が発生している。現在の多くのプロジェクトでは、未使用のポインタをそのインタフェースのパラメータとして使用しており、スマートポインタ用のインタフェースはありません。 QMainWindow::setCentralWidgetC++ 11 Smart PointerとRaw Pointerインタフェースを併用する安全な方法はありますか?

は、一貫性のある形を保つために、私はこのセグメントのよう get()から保存されたポインタを渡す必要があります:

QMainWindow win; 

std::shared_ptr<QWidget> scrollArea{ std::make_shared<QScrollArea>() }; 
// QScrollArea is a derived class of QWidget. 

win.setCentralWidget(scrollArea.get()); 

しかし、私はQtの中の他の方法はscrollAreaの格納されているポインタにオペレータdeleteを実行するかどうかを確認することができません。

Qtのいくつかの方法でメモリリークやその他の問題が発生するのでしょうか?

最新のC++ Standard CDを確認したところ、何も見つかりませんでした。これは未定義の動作だと思われます。

これが未定義の動作で危険な場合は、は生ポインタのインターフェイスでスマートポインタを使用する安全な方法はありますか?

+2

Qtが 'delete'を実行するかどうかわからない場合は、どのようにして現在どのメモリリークもないことを確認しますか? – hmjd

+2

「ポインタを2回削除すると問題が発生しますか?」と尋ねた場合と同じです。 –

+0

@ W.B。私の主な目的は、この場合の解決策を見つけることです。 – UniversE

答えて

16

一般的にこのような方法はありません。使用するそれぞれの "レガシー"インターフェイスについて、そのドキュメントが所有権とどのように相互作用するかを確認する必要があります(stdスマートポインタがカプセル化します)。 1つのオブジェクトは、1つの所有権スキームでしか管理できません。

特にQtでは、確かにではありません。スマートポインタとQt管理を混在させても安全です。 QObjectのQtの親子関係には所有権セマンティクスが含まれているため、他の所有者スキーム(例えばstdスマートポインタなど)と安全に混在させることはできません。

リンク先のQtドキュメントには、「QMainWindowウィジェットの所有権を取り、ポインタの所有権を取り、適切なタイミングで削除することに注意してください。

3

残念ながら、未加工のポインタを使用するインターフェイスを使用している場合、メソッドが提供されたポインタの所有権を取得するかどうかをドキュメントで調べる必要があります。

所有権がある場合は、所有権を機能に移すには、.release()を呼び出す必要があります。関数が所有権を取得しない場合は、.get()でオブジェクトを渡します。

3

Qtのいくつかの方法ではメモリリークやその他の問題が発生しますか?

メモリが放棄されているため、メモリリークが発生しません。しかし、QTとshared_ptrの両方がそのメモリ上でdeleteを呼び出すため、ヒープの破損(通常はUB)が発生する可能性があります。

スマートポインタを生ポインタのインターフェイスに使用する安全な方法はありますか?

確かに。無関係なエンティティに同じメモリを管理させないでください。そのため、できるだけshared_ptrの代わりにunique_ptrを使用するのが賢明です。 unique_ptr.release()と呼ぶと、スマートポインタのコントロールからメモリを解放することができ、QTを制御できるようになります。

もちろん、あなたが自分でメモリを管理しなければならないときや、QTがあなたのためにそれを行うときには、ドキュメントをチェックする必要があります。

3

生ポインタを使用するインタフェースを使用している場合、それらのポインタの存続期間の責任者を知っていなければならないという問題があります。

shared_ptrをミックスに追加してもこれは変わりません。

インターフェイスがオブジェクトを削除する可能性がある場合は、std::shared_ptrを安全に使用することはできません。 std::shared_ptrはオブジェクトの存続時間を制御する必要があり、これを回避する方法はありません(別の間接レベルを追加することはありません)

std::unique_ptrのうちいくつかを使用できます。インタフェースがポインタを削除しない場合は、ptr.get()を安全に渡すことができます。インタフェースがそのオブジェクトの存続期間の所有権を取得する場合は、ptr.release()を渡して、あなた自身の生涯を制御しないでください。

すべてで、レガシーコードベースでもスマートポインタからいくらかの有用性を得ることができますが、少し注意する必要があります。

1

しかし、Qtの他のメソッドがscrollAreaの格納されたポインタに対して演算子の削除を実行するかどうかを確認することはできません。

ウィジェットに親がある場合、QTのメモリ管理によってそのオブジェクトが解放されます。その場合、スマートポインタを使用してはいけません。これは、アプリケーションがそのポインタを2回解放しようとし、それが未定義の動作だからです。

関連する問題