2013-10-14 30 views
2

在Qt工程我有一个方法Qt的缺失指针方法

void ProtocolHandler::interpretData(uint8_t packet_id){ 
    PacketClass *packet = new RSP2StatusPacket(_packet_buf); 
    emit packetReceived(packet); 
} 

其中I声明类型PacketClass的目的数据包,然后我发射信号

packetReceived (PacketClass*) 

在另一类我有以下插槽:

void ReceiverCommands::processReceivedPacket(PacketClass* pkt) 
{ 
    status_packet *payload = pkt->getPayload(); 

    delete pkt 
} 

在插槽方法中删除较新的PacketClass *包是否正确? 有时我的程序崩溃,所以删除信号/槽中传递的指针的最佳方法是什么(我想我必须删除pkt,因为我在“interpretData”方法中实例化了一个新数据包)。

+0

你不应该这样做,如果有连接到信号多个时隙(或甚至一个双连接) –

+0

在PacketClass的情况下,不从继承自QObject,我会使用的包装尝试一些方法类和QSharedPointer,当所有插槽完成处理时确保删除对象。在另一种情况下,Merlin069的答案是正确的。 – Jairo

+0

@Jairo:你会需要一个包装类吗? –

回答

1

假设PacketClass从QObject的衍生,然后调用deleteLater功能: -

pkt->deleteLater(); 

这将处理删除对象在合适的时间,就已经通过处理信号和槽后并且控制返回时到事件循环。

见deleteLater here的文档,这也是相关的Qt4

+1

如果信号连接到多线程中的插槽,这将会失败。这不是一个好建议。真的,你不应该使用裸指针将数据所有权转移给插槽。这就是它的全部。 –

+0

你也不清楚应该在哪里调用deleteLater函数 - 只能在信号中执行,而不是在插槽中执行。至少你需要传递一个'QPointer',这样如果有人滥用这个代码并将它附加到另一个线程中的一个槽中,那么所述线程将不会有悬挂指针,但能够优雅地崩溃,引脚 - 指出问题。 –

+0

或者,至少你需要在'ProtocolHandler'中重新实现'connectNotify',并跟踪连接的对象以确保它们没有错误的线程(或移动到错误的线程!)。 –

2

可以有连接到信号的时隙的任意数(包括零和不止一个!),所以你应该永远期待一个插槽来释放通过光标指针传递的内存。

你应该通过一个QSharedPointer<PacketClass>并使用它。它会在需要时进行删除。

typedef QSharedPointer<PacketClass> PacketClassPtr; 
Q_DECLARE_METATYPE(PacketClassPtr) 

ProtocolHandler { 
    ... 
    Q_SIGNAL void packetReceived(PacketClassPtr packet); 
} 

void ProtocolHandler::interpretData(uint8_t packet_id){ 
    PacketClassPtr packet(new RSP2StatusPacket(_packet_buf)); 
    emit packetReceived(packet); 
} 

void ReceiverCommands::processReceivedPacket(PacketClassPtr pkt) 
{ 
    status_packet *payload = pkt->getPayload(); 
}