5

在这里我们可以读到没有复制构造和复制赋值运算符可评估。但是在这里我们可以阅读它qRegisterMetaType并且Q_DECLARE_METATYPE必须有公共默认构造函数、公共复制构造函数和公共析构函数。问题是:谁在说谎?还是我没有正确理解?

4

3 回答 3

6

一切都是真的:
1.QObject不能复制,它的所有后代也不能复制。
2.Q_DECLARE_METATYPE接受具有公共构造函数、复制构造函数和析构函数的对象。

没有矛盾,因为你不能QObjectQ_DECLARE_METATYPE.

编辑:

当您将类转换为QVariant它时,使用复制构造函数来制作对象的副本:

 void *ptr = QMetaType::construct(x->type, copy);
于 2014-09-17T12:43:10.850 回答
2

您当然可以在派生自 的类中实现复制构造函数和赋值运算符QObject,但不能引用已删除的基类复制构造函数和赋值运算符。你需要自己动手。

因此,您需要接受这样一个事实,即复制构造或分配不会影响到源对象或目标对象的信号/插槽连接。您还必须决定在复制时如何处理亲子关系——三种可能的选择中的任何一种都是完全任意的——这就是为什么在大多数情况下复制对象没有意义,它太容易出错了。

例如,使用复制和交换习语

class CopyableObject : public QObject
{
  Q_OBJECT
public:
  friend void swap(CopyableObject & first, CopyableObject & second) {
    // d_ptr swap doesn't take care of parentage
    QObject * firstParent = first.parent();
    QObject * secondParent = second.parent();
    first.setParent(0);
    second.setParent(0);
    first.d_ptr.swap(second.d_ptr);
    second.setParent(firstParent);
    first.setParent(secondParent);
  }
  CopyableObject(const CopyableObject & other) : QObject(other.parent()) {
    Q_ASSERT(thread() == other.thread());
    setObjectName(other.objectName());
    blockSignals(other.signalsBlocked());
  }
  CopyableObject(QObject * parent = 0) : QObject(parent) {}
  // C++11 only
  #if __cplusplus >= 201103L
  CopyableObject(CopyableObject && other) : CopyableObject() {
    swap(*this, other);
  }
  #endif
  CopyableObject & operator=(CopyableObject other) {
    swap(*this, other);
    return *this;
  }
};

请注意,您需要重新实现swap派生类的函数。

于 2014-09-19T17:20:26.147 回答
2

Q_DECLARE_METATYPE如果您想将它们用作 SIGNAL/SLOT 参数,宏用于生成自定义用户类型的信息。

例子:

struct MyInfo
{
  QString name;
  QDate birthday;
};

Q_DECLARE_METATYPE( MyInfo )

// ... somewhere in cpp:
{
  QObject::connect( obj1, SIGNAL( newData( MyInfo ), SLOT( onNewData( MyInfo ) ) );
}

如果没有Q_DECLARE_METATYPE宏,您将无法MyInfo作为信号或插槽参数传递。

如果您使用跨线程连接(Qt::QueuedConnection,Qt::BlockingQueuedConnection等),您还需要使用qRegisterMetatype<MyInfo>();call 注册您的类型。


但是可以,用于Q_DECLARE_METATYPE将 POINTERS 注册到 QObjects。例如:

class MyItem
  : public QObject
{
  Q_OBJECT
//...
};

Q_DECLARE_METATYPE( MyItem * )
// or event better Q_DECLARE_METATYPE( QSharedPointer< MyItem > )

指针是 POD 类型,可以构造、复制等。

于 2014-09-17T12:51:24.143 回答