C++ Qt删除指针法

C++ Qt删除指针法,c++,qt,qt4,C++,Qt,Qt4,在Qt项目中,我有一个方法 void ProtocolHandler::interpretData(uint8_t packet_id){ PacketClass *packet = new RSP2StatusPacket(_packet_buf); emit packetReceived(packet); } 在这里,我声明一个PacketClass类型的对象包,然后发出信号 packetReceived (PacketClass*) 在另一个类中,我有以下插槽: voi

在Qt项目中,我有一个方法

void ProtocolHandler::interpretData(uint8_t packet_id){
    PacketClass *packet = new RSP2StatusPacket(_packet_buf);
    emit packetReceived(packet);
}
在这里,我声明一个PacketClass类型的对象包,然后发出信号

packetReceived (PacketClass*)
在另一个类中,我有以下插槽:

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

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

假设PacketClass是从QObject派生的,然后调用deleteLater函数:-

pkt->deleteLater();
这将处理在正确的时间删除对象,在对象处理完信号和插槽之后,以及当控制返回到事件循环时


请参阅deleteLater的文档,该文档也与Qt4相关。信号上可以连接任意数量的插槽(包括零个和多个!),因此您永远不要期望插槽释放通过裸指针传递的内存

您应该传递一个
QSharedPointer
并使用它。它将在需要时进行删除

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();
}
typedef QSharedPointer PacketClassPtr;
Q_DECLARE_元类型(PacketClassPtr)
原型处理器{
...
接收到Q_信号无效包(PacketClassPtr包);
}
void ProtocolHandler::解释数据(uint8\u t数据包\u id){
PacketClassPtr数据包(新的RSP2StatusPacket(_packet_buf));
发出已接收的数据包(数据包);
}
void ReceiverCommands::processReceivedPackage(PacketClassPtr pkt)
{
状态_packet*payload=pkt->getPayload();
}

您不应该这样做,如果有多个插槽连接到该信号(甚至是双连接),如果PacketClass不是从QObject派生的,我会尝试使用包装类和QSharedPointer的一些方法,以确保在所有插槽完成处理后删除对象。在另一种情况下,Merlin069的答案是正确的。@Jairo:你为什么需要一个包装类?如果你能保证,deleton只会发生一次,那么是的,这是正确的(不管该类是否从QObject派生),并且它本身不能成为崩溃的原因。但是这种方法看起来有点异味:)@KubaOber:是的,你是对的。不需要包装器类。在这种情况下,QSharedPointer就足够了。有时我认为我需要添加额外的保护以获得更多的控制,在这种情况下,以确保对象删除;但是聪明的指针会处理好它。感谢您的评论。如果信号连接到多线程中的插槽,那么这将非常失败。这不是一个好建议。实际上,您不应该使用裸指针将数据所有权转移到插槽。这就是问题的全部。您还不清楚应该在哪里调用
deleteLater
——只有在信号中才有意义,而不是在插槽中。至少,您需要传递一个
QPointer
,这样,如果有人误用此代码并将其附加到另一个线程的插槽中,该线程将不会有悬空指针,但能够正常崩溃,锁定问题。或者,至少您需要在
ProtocolHandler
中重新实现
connectNotify
,并跟踪连接的对象,以确保它们不在错误的线程中(或移动到错误的线程!)。@KubaOber,所有这些都是公平的,尽管我假设(可能是错误的)这是一个单线程应用程序。只有一点,你说deleteLater应该在信号中完成…你这是什么意思?我以为信号没有功能体?