4

私はオブジェクトで信号を発するオブジェクトを持っています:

MyObj *obj = this->generateObj();
emit newObjSignal(obj);
delete obj;

そして、これにつながる人が1人以上います。問題は、オブジェクトがシグナルを受信する前に削除呼び出しが呼び出されることです。どうすればこれに対処できますか?

4

3 に答える 3

7

スマート ポインターを使用すると、メモリ管理が自動的に処理され、次のことが確実になります。

  1. ダングリング ポインターはありません。
  2. メモリリークはありません。

この場合、私にはstd::shared_ptr<>(またはstd::tr1::shared_ptr<>C boost::shared_ptr<>++11 を使用していない場合は) 正しい選択だと思われます。

#include <memory> // For std::shared_ptr<>
// ...
std::shared_ptr<MyObj> obj(this->generateObj());
emit_new_signal(obj);
// delete obj; // <== No need for this anymore!

また、ハンドラー関数はstd::shared_ptr<MyObj>生のポインターではなくを受け入れる必要があることに注意してくださいMyObj*。ただし、これらのハンドラー内のコードは変更する必要はありません。std::shared_ptroperator ->

一般に、newC++11 では の使用は推奨されておらず、可能な場合は を使用std::make_shared<>して s を作成する必要があることに注意してくださいshared_ptr。したがって、メンバー関数を書き直して、ではなく をgenerateObj()返すようにし、オブジェクトをインスタンス化するために内部で使用できるようにすることができます。std::shared_ptr<MyObj>MyObj*std::make_shared<MyObj>()

ノート:

コメントでGeierが指摘したように、Qt には独自のスマート ポインター クラスQSharedPointerがあり、これを使用することをお勧めします。

于 2013-03-23T18:39:16.913 に答える
3

を使用できますがQSharedPointer、動的メモリ割り当てを使用しないという別のアプローチもあります。したがって、コードは次のようになります-

MyObj obj = this->generateObj();
emit newObjSignal(obj);

これにより、明らかに のコピーMyObjが作成されます。Qt は通常、暗黙的な共有またはコピー オン ライトを使用してこの問題を解決します。

独自のクラスでこの暗黙的な共有メカニズムを使用するには、クラスの構造を変更して、 と を使用する必要がありますQSharedDataQSharedDataPointer

class MyObjData : public QSharedData {
public:
    int variable;
};

class MyObj {
    MyObj() : d(new MyObjData) {}
    int foo() { return d->variable; }
private:
    QSharedDataPointer<MyObjData> d;
};

この方法では、 のコピーはMyObj非常に安価になり、信号を介して簡単に渡すことができます。

これは、QSharedPointer を使用するよりもはるかにクリーンな IMO です。

于 2013-03-23T19:18:52.697 に答える
1

シグナル「newObjSignal(obj)」が消費されるスロットで別のシグナルを送信してから、deletelater を呼び出します。

connect(someobject,SIGNAL(finish()),obj,SLOT(deleteLater()));

于 2013-03-23T20:16:15.050 に答える