【问题标题】:Cannot add my class in the QList无法在 QList 中添加我的课程
【发布时间】:2016-03-31 10:28:08
【问题描述】:

我有从 QObject 交付的自定义类:

class Client : public QObject
{
    Q_OBJECT
    friend class Server;
public:
    Client(QTcpSocket *socket, QObject *parent = 0);
private:
    QTcpSocket *mSocket;
};

并尝试将其添加到我的列表(QList)中

auto socket = mServer->nextPendingConnection();
Client client(socket);
mClients.append(client);

接下来输出:

/usr/include/x86_64-linux-gnu/qt5/QtCore/qlist.h:521:需要来自 'void QList::append(const T&) [with T = Client]'
...
/usr/include/x86_64-linux-gnu/qt5/QtCore/qlist.h:372:错误:使用 删除函数'Client::Client(const Client&)' if (QTypeInfo::isLarge || QTypeInfo::isStatic) n->v = new T(t);

如何正确地将我的对象添加到列表中?

【问题讨论】:

  • 都是Client类的代码吗?这很奇怪,因为没有删除的复制构造函数,也没有没有复制构造函数的成员。
  • 是的,现在都是代码。当然,它在原型的.cpp文件中都有实现。
  • 我可以不使用复制构造函数而只移动列表中的对象吗?
  • QObject 不应被复制,而是将其设为智能指针列表(例如 shared_ptrs/QSharedPointers)。

标签: c++ qt c++11 qlist


【解决方案1】:

我猜你应该为你的Client 类定义copy constructor,它因为valid reason 而被删除,看起来QList 想要它。

【讨论】:

  • 用户定义的构造函数并不意味着复制构造函数会被删除。
  • 它被删除是因为 QObjects 删除了它,原因很充分:复制 QObject 没有什么意义(信号/插槽连接语义会中断)。 QObjects 不能被明智地用作值类型,因此应该在堆上创建它们并管理它们,例如作为共享指针 (QList<QSharedPointer<Client>>)。或者重新考虑该类是否需要从 QObject 继承。
  • 我这样用过:auto client = QSharedPointer<Client>(new Client(socket)); 对吗?
【解决方案2】:

QObject 具有私有复制构造函数和赋值运算符。您应该存储智能指针列表,而不是对象。

你不应该为从QObject派生的类定义复制构造函数。

QObject 子类的实例不应被视为值 可以复制或分配,但作为唯一身份。这意味着 当您创建自己的 QObject 子类(导演或 间接的),你不应该给它一个复制构造函数或赋值 运算符。

没有复制构造函数或赋值运算符

QObject 既没有复制构造函数也没有赋值运算符。 这是设计使然。实际上,它们是声明的,但是在私有的 带有宏 Q_DISABLE_COPY() 的部分。事实上,所有 Qt 类 派生自 QObject(直接或间接)使用此宏声明 它们的复制构造函数和赋值运算符是私有的。

【讨论】:

  • @Jeka 不,append 和 QList 中没有其他函数的右值引用重载,正如我在文档中看到的那样。
【解决方案3】:

不要使用基于 QObject 的类的复制。使用指针:

QList<Client*> mClients;
Client* cln = new Client( socket );
mClients << cln;
....

或者你可以使用智能指针

【讨论】:

  • 谢谢!我不知道这种方式
  • @ghostman 不要忘记删除使用 new 运算符创建的对象。使用正确的父母身份也是一个好主意。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-03
  • 1970-01-01
  • 1970-01-01
  • 2018-11-14
相关资源
最近更新 更多