私はオブジェクトで信号を発するオブジェクトを持っています:
MyObj *obj = this->generateObj();
emit newObjSignal(obj);
delete obj;
そして、これにつながる人が1人以上います。問題は、オブジェクトがシグナルを受信する前に削除呼び出しが呼び出されることです。どうすればこれに対処できますか?
私はオブジェクトで信号を発するオブジェクトを持っています:
MyObj *obj = this->generateObj();
emit newObjSignal(obj);
delete obj;
そして、これにつながる人が1人以上います。問題は、オブジェクトがシグナルを受信する前に削除呼び出しが呼び出されることです。どうすればこれに対処できますか?
スマート ポインターを使用すると、メモリ管理が自動的に処理され、次のことが確実になります。
この場合、私には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_ptr
operator ->
一般に、new
C++11 では の使用は推奨されておらず、可能な場合は を使用std::make_shared<>
して s を作成する必要があることに注意してくださいshared_ptr
。したがって、メンバー関数を書き直して、ではなく をgenerateObj()
返すようにし、オブジェクトをインスタンス化するために内部で使用できるようにすることができます。std::shared_ptr<MyObj>
MyObj*
std::make_shared<MyObj>()
ノート:
コメントでGeierが指摘したように、Qt には独自のスマート ポインター クラスQSharedPointerがあり、これを使用することをお勧めします。
を使用できますがQSharedPointer
、動的メモリ割り当てを使用しないという別のアプローチもあります。したがって、コードは次のようになります-
MyObj obj = this->generateObj();
emit newObjSignal(obj);
これにより、明らかに のコピーMyObj
が作成されます。Qt は通常、暗黙的な共有またはコピー オン ライトを使用してこの問題を解決します。
独自のクラスでこの暗黙的な共有メカニズムを使用するには、クラスの構造を変更して、 と を使用する必要がありますQSharedData
。QSharedDataPointer
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 です。
シグナル「newObjSignal(obj)」が消費されるスロットで別のシグナルを送信してから、deletelater を呼び出します。
connect(someobject,SIGNAL(finish()),obj,SLOT(deleteLater()));