Qt事件数据析构函数
Qt event data destructor
假设有一个带信号的qt对象。该对象发出一个信号,其中包含分配在堆上的一些对象 (new/malloc)。事件的析构函数释放所有分配的数据。如果没有连接到 qt-object 信号,这些数据会以任何方式释放吗?如果侦听器在其信号槽中接收到事件之前关闭连接?
添加:
带有缩短的示例。
class MyEvent { virtual ~MyEvent(); }; // root class for all my project events
class MyEventQueue {
MyEventQueue(); // initialize mutex
virtual ~MyEventQueue(); // delete and release all events from events_
void push_back( MyEvent *); // atomic-push event
MyEvent *pop_front(); // atomic-pop event
pthread_mutex_t sync_; // mutex for atomic operations
std::queue<MyEvent *> events_; // queue of events
};
class MyEvent1 : public MyEvent {
MyEvent1( char *);
~MyEvent1() { delete[] data; }
char *data;
};
class MyWriter {
...;
void eval();
signals: void send1( MyEventQueue *);
MyEventQueue queue_;
};
class MyReader {
...;
slots: void recv1( MyEventQueue *);
};
class MyController {
...;
}
MyWriter 和 MyReader 是在一个进程的不同线程中工作的独立参与者。
void MyWriter::eval() {
...;
queue_.push_back( new MyEvent1( ...));
emit send1( &queue_);
}
void MyReader::recv1( MyEventQueue *queue) {
if ( MyEvent *event = queue->pop_front() ) {
// event is delivered to MyReader
...;
delete event;
}
}
如果发送的事件已送达并被接受,它将在 MyReader 中删除。以其他方式,事件将保存在 MyWriter::queue_.
中
MyController 作为 MyWriter 和 MyReader 的 dispatcher/manager。它还实现了与其他功能块的通信。在(外部)数据处理周期结束时,MyController 停止 MyWriter、MyReader(它们的线程以及它们的 qt 事件循环)。然后它关闭 MyWriter 和 MyReader 之间的连接。如果某些事件由 MyWriter 发送,但未被 MyReader 接受,则分配的数据将在 ~MyWriter() -> queue_ 的析构函数中释放。
(对于多个读者,我在 MyController 中使用显式重新发送事件处理或仅一对一连接,在这种情况下,MyController 用作具有自身事件队列的路由器。)
主要原因是数据处理的流水线化和并行化。
我怀疑我是否重复了 qt-engine 的工作。当然,也许还有更好的解决办法。
关于向信号传递参数的一般建议
是否销毁作为信号参数传递的对象取决于您。请注意,多个插槽可能会连接到同一个信号,这可能会导致多次破坏对象。
一些(常见的)可能性是:
- 通过 const 引用传递。当使用 queued connection 时,Qt 将创建一个副本。否则将不会复制。
- 按值传递。对基本类型有用,否则通过 const 引用传递。
- 传递共享指针。
另一个选项可能是使用 QObject::isSignalConnected
检查插槽是否连接到信号。如果参数需要大量资源来构建,此函数对于避免信号发射特别有用。但是,我不建议您使用此选项,因为它不能解决多个插槽连接到同一信号的情况。
另一种可能性是实现您自己的回调方法,这将允许您强制执行唯一的回调方法。
假设有一个带信号的qt对象。该对象发出一个信号,其中包含分配在堆上的一些对象 (new/malloc)。事件的析构函数释放所有分配的数据。如果没有连接到 qt-object 信号,这些数据会以任何方式释放吗?如果侦听器在其信号槽中接收到事件之前关闭连接?
添加:
带有缩短的示例。
class MyEvent { virtual ~MyEvent(); }; // root class for all my project events
class MyEventQueue {
MyEventQueue(); // initialize mutex
virtual ~MyEventQueue(); // delete and release all events from events_
void push_back( MyEvent *); // atomic-push event
MyEvent *pop_front(); // atomic-pop event
pthread_mutex_t sync_; // mutex for atomic operations
std::queue<MyEvent *> events_; // queue of events
};
class MyEvent1 : public MyEvent {
MyEvent1( char *);
~MyEvent1() { delete[] data; }
char *data;
};
class MyWriter {
...;
void eval();
signals: void send1( MyEventQueue *);
MyEventQueue queue_;
};
class MyReader {
...;
slots: void recv1( MyEventQueue *);
};
class MyController {
...;
}
MyWriter 和 MyReader 是在一个进程的不同线程中工作的独立参与者。
void MyWriter::eval() {
...;
queue_.push_back( new MyEvent1( ...));
emit send1( &queue_);
}
void MyReader::recv1( MyEventQueue *queue) {
if ( MyEvent *event = queue->pop_front() ) {
// event is delivered to MyReader
...;
delete event;
}
}
如果发送的事件已送达并被接受,它将在 MyReader 中删除。以其他方式,事件将保存在 MyWriter::queue_.
中MyController 作为 MyWriter 和 MyReader 的 dispatcher/manager。它还实现了与其他功能块的通信。在(外部)数据处理周期结束时,MyController 停止 MyWriter、MyReader(它们的线程以及它们的 qt 事件循环)。然后它关闭 MyWriter 和 MyReader 之间的连接。如果某些事件由 MyWriter 发送,但未被 MyReader 接受,则分配的数据将在 ~MyWriter() -> queue_ 的析构函数中释放。
(对于多个读者,我在 MyController 中使用显式重新发送事件处理或仅一对一连接,在这种情况下,MyController 用作具有自身事件队列的路由器。)
主要原因是数据处理的流水线化和并行化。
我怀疑我是否重复了 qt-engine 的工作。当然,也许还有更好的解决办法。
关于向信号传递参数的一般建议
是否销毁作为信号参数传递的对象取决于您。请注意,多个插槽可能会连接到同一个信号,这可能会导致多次破坏对象。
一些(常见的)可能性是:
- 通过 const 引用传递。当使用 queued connection 时,Qt 将创建一个副本。否则将不会复制。
- 按值传递。对基本类型有用,否则通过 const 引用传递。
- 传递共享指针。
另一个选项可能是使用 QObject::isSignalConnected
检查插槽是否连接到信号。如果参数需要大量资源来构建,此函数对于避免信号发射特别有用。但是,我不建议您使用此选项,因为它不能解决多个插槽连接到同一信号的情况。
另一种可能性是实现您自己的回调方法,这将允许您强制执行唯一的回调方法。