在这里我们可以读到没有复制构造和复制赋值运算符可评估。但是在这里我们可以阅读它qRegisterMetaType
并且Q_DECLARE_METATYPE
必须有公共默认构造函数、公共复制构造函数和公共析构函数。问题是:谁在说谎?还是我没有正确理解?
3 回答
一切都是真的:
1.QObject
不能复制,它的所有后代也不能复制。
2.Q_DECLARE_METATYPE
接受具有公共构造函数、复制构造函数和析构函数的对象。
没有矛盾,因为你不能QObject
用Q_DECLARE_METATYPE
.
编辑:
当您将类转换为QVariant
它时,使用复制构造函数来制作对象的副本:
void *ptr = QMetaType::construct(x->type, copy);
您当然可以在派生自 的类中实现复制构造函数和赋值运算符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
派生类的函数。
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 类型,可以构造、复制等。