继承QObject后触发「使用已删除函数」编译错误的问题排查
问题分析与解决方案
这个问题的核心原因很明确:QObject及其子类是不可拷贝的,而你使用的QQueue<commandTcp>需要存储的元素支持拷贝操作,两者冲突导致了编译错误。
为什么会报错?
QObject类的拷贝构造函数QObject::QObject(const QObject&)被标记为private且显式删除,这是Qt的设计——QObject体系基于对象身份而非值语义,禁止拷贝以避免信号槽连接、对象生命周期管理等资源的混乱。- 当你的
commandTcp继承QObject后,编译器会自动隐式删除它的默认拷贝构造函数(因为基类的拷贝构造不可用)。 QQueue::enqueue()方法需要将传入的对象拷贝到队列中,而现在commandTcp没有可用的拷贝构造函数,因此编译器抛出了一系列关于“使用已删除函数”的错误。
在你让commandTcp继承QObject之前,它是普通C++类,编译器会生成默认的拷贝构造函数,QQueue自然可以正常工作。
可行的解决方案
根据你的需求,有两种常见的处理方式:
方案1:如果commandTcp不需要信号槽功能,移除QObject继承
如果commandTcp只是用来存储数据,不需要Qt的信号槽、父子对象管理等QObject特性,最简单的办法就是去掉QObject继承和Q_OBJECT宏:
// commandTcp.h 修改后 #ifndef COMMANDTCP_H #define COMMANDTCP_H #include <QByteArray> class commandTcp { // 移除QObject继承 private: QByteArray storeCommand; int arraySize; int destinationAddress; int length; int command; public: commandTcp(int, int, int, QByteArray, int); }; #endif // COMMANDTCP_H
这样commandTcp会恢复默认的拷贝构造函数,QQueue<commandTcp>就能正常工作了。
方案2:如果必须保留QObject继承,改用智能指针存储
如果commandTcp必须继承QObject(比如需要信号槽功能),那么你需要让QQueue存储指向commandTcp对象的智能指针,避免直接拷贝QObject子类。推荐使用QSharedPointer自动管理内存:
- 修改
queueTcp.h:
#ifndef QUEUETCP_H #define QUEUETCP_H #include <QObject> #include <commandtcp.h> #include <QQueue> #include <QSharedPointer> class queueTcp: public QObject { // 无需继承QQueue,直接组合队列对象 Q_OBJECT private: QQueue<QSharedPointer<commandTcp>> m_queue; // 用智能指针队列替代原类型 public: queueTcp(); void newCommand(); }; #endif // QUEUETCP_H
- 修改
queueTcp.cpp:
#include "queuetcp.h" queueTcp::queueTcp() { } void queueTcp::newCommand() { // 注意构造参数顺序要匹配commandTcp的定义,第四个参数需传入合法QByteArray auto temp = QSharedPointer<commandTcp>::create(63, 8, 208, QByteArray(), 1); m_queue.enqueue(temp); }
另外需要注意:你在newCommand()中调用commandTcp构造函数时,第四个参数传了0,但构造函数要求的是QByteArray类型,这会导致额外编译错误,需要改成QByteArray()或其他合法的QByteArray对象。
内容的提问来源于stack exchange,提问作者Julian
相关产品推荐
相关产品推荐

