你如何处理内存管理和信号/插槽
How do you deal with memory management and signal/slots?
我有一个用对象发出信号的对象:
MyObj *obj = this->generateObj();
emit newObjSignal(obj);
delete obj;
和我有一个或多个连接到这个的人。问题是在对象接收到信号之前调用了delete调用。我该如何处理呢?
使用智能指针,这样内存管理将自动处理,您将确保您将有:
- 没有悬浮指针; 没有内存泄漏。
在这种情况下,在我看来,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通常通过使用隐式共享或写时复制来解决这个问题。
为了让你自己的类使用这种隐式共享机制,你必须改变你的类的结构,并使用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)"被消耗的槽中发出另一个信号,然后调用deleteelater。
connect(someobject,SIGNAL(finish()),obj,SLOT(deleteLater()));
- Qt VTK交互风格的信号到小部件
- 获取日期异步信号安全吗?如果在信号处理程序中使用,它会导致死锁吗
- 当vector是tje全局变量时,c++中vector的内存管理
- 如何将点击的信号和插槽添加到qt中的自定义按钮中
- 如何在没有信号的情况下从C++执行QML插槽
- 线程之间的布尔停止信号
- 如何维护资源管理器项目视图中当前可见的项目列表
- 如何在信号处理程序和普通函数中对全局变量进行互斥读写操作
- 如何在GTK程序运行时禁用屏幕保护程序/电源管理/屏幕消隐
- 当用户在qtablewidget中输入单元格时,如何获得信号?C++
- 有可能在信号处理程序中设置promise吗
- 资源管理设计模式
- 代码在我的计算机上运行良好,但是在将其提交给coursera时遇到未知的信号11问题
- 使用"Task"函数指针队列定义作业管理器
- 在条件变量中触发错误信号的频率是多少
- 用户类中的多签名信号管理
- 使用信号和线程的事件管理器
- Boost信号连接管理
- 你如何处理内存管理和信号/插槽
- Qt:等待具有超时管理的信号