我有一个发出信号与对象的对象:你如何处理内存管理和信号/插槽?
MyObj *obj = this->generateObj();
emit newObjSignal(obj);
delete obj;
,我有谁连接到这一个或更多的人。问题是在对象接收信号之前调用删除调用。我如何处理这个问题?
我有一个发出信号与对象的对象:你如何处理内存管理和信号/插槽?
MyObj *obj = this->generateObj();
emit newObjSignal(obj);
delete obj;
,我有谁连接到这一个或更多的人。问题是在对象接收信号之前调用删除调用。我如何处理这个问题?
使用智能指针,使内存管理会自动处理,你会相信你将有:
在这种情况下,在我看来std::shared_ptr<>
(或std::tr1::shared_ptr<>
或boost::shared_ptr<>
,如果你不与C++ 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 ->
的超载。
请注意,通常,在C++ 11中不鼓励使用new
,并且在可能的情况下,应该使用std::make_shared<>
来创建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通常通过使用implicit sharing或写时复制来解决此问题。
为了让自己的类使用这种隐含的共享机制,你将不得不改变你的类的结构和使用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
副本会很便宜,你可以轻松传递信号。
这是IMO比使用QSharedPointer更清洁。
只在消耗信号“newObjSignal(obj)”的插槽中发出另一个信号,然后调用deletelater。
connect(someobject,SIGNAL(finish()),obj,SLOT(deleteLater()));
,信号/槽机制是通过缺省同步(即,没有问题,因为删除被称为当所有时隙都已经被称为),除非你是跨线程信令(或显式地指定一个延迟连接政策)。如果您的确在跨线程发信号,则必须小心使用智能指针解决方案,因为它们可能不是线程安全的。 – 2013-03-23 20:21:45