我有一个对象发出带有对象的信号:
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!
另请注意,处理程序函数必须接受 astd::shared_ptr<MyObj>
而不是原始指针MyObj*
,但这些处理程序内的代码不必更改,因为std::shared_ptr
提供了operator ->
.
请注意,一般来说,new
在 C++11 中不鼓励使用 of,并且在可能的情况下应该使用std::make_shared<>
to create shared_ptr
s。因此,您可能需要重写您的generateObj()
成员函数,使其返回 astd::shared_ptr<MyObj>
而不是 a MyObj*
,并让它在std::make_shared<MyObj>()
内部使用来实例化对象。
笔记:
正如Geier在评论中指出的那样,Qt 有自己的智能指针类QSharedPointer,您可能想要使用它。
虽然您可以使用 a 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 更干净。
只需在使用信号“newObjSignal(obj)”的插槽中发出另一个信号,然后调用 deletelater。
connect(someobject,SIGNAL(finish()),obj,SLOT(deleteLater()));