Here 우리는 복사 구성 및 복사 할당 연산자를 평가할 수 없음을 읽을 수 있습니다. 그러나 here 우리는 qRegisterMetaType
과 Q_DECLARE_METATYPE
에 public 기본 생성자, 공용 복사본 생성자 및 공용 소멸자가 있어야한다는 것을 알 수 있습니다. 문제는 누가 거짓말을하고 있는가? 아니면 제대로 이해하지 못했습니까?QObject의 하위 클래스에 대한 복사 생성자가 있습니까?
답변
모든 것이 사실임 :
1. QObject
은 복사 할 수 없으며 모든 자손도 복사 할 수 없습니다.
2. Q_DECLARE_METATYPE
은 public 생성자, 복사 생성자 및 소멸자가있는 객체를 허용합니다.
QObject
자손을 Q_DECLARE_METATYPE
으로 등록 할 수 없기 때문에 모순이 없습니다. 당신이 QVariant
에 클래스를 변환 할 때
그것은 개체의 복사본을 만들기 위해 복사 생성자를 사용합니다 : EDIT
void *ptr = QMetaType::construct(x->type, copy);
Q_DECLARE_METATYPE
매크로 경우, 사용자 정의 사용자 유형에 대한 정보를 생성하는 데 사용됩니다 당신은 그것들을 SIGNAL/SLOT 인수로 사용하기를 원한다.
예 : 신호 또는 슬롯 인수로 MyInfo
를 통과하지 수
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
없이.
크로스 스레드 연결 (Qt::QueuedConnection
, Qt::BlockingQueuedConnection
등)을 사용하는 경우 qRegisterMetatype<MyInfo>();
호출로 유형을 등록해야합니다.
하지만 괜찮습니다, QObjects에 대한 포인터를 등록 Q_DECLARE_METATYPE
를 사용합니다. 예를 들어 '
class MyItem
: public QObject
{
Q_OBJECT
//...
};
Q_DECLARE_METATYPE(MyItem *)
// or event better Q_DECLARE_METATYPE(QSharedPointer<MyItem>)
포인터
당신은 확실히QObject
에서 파생되는 클래스의 복사 생성자와 대입 연산자를 구현할 수
등으로 구성 복사 할 수 있습니다 POD 유형은,하지만 당신은 할 수 삭제 된 기본 클래스 복사 생성자 및 대입 연산자를 참조하십시오. 당신은 자신을 굴려야합니다.
따라서 복사 구성이나 할당이 원본 또는 대상 개체에 대한 신호/슬롯 연결에 영향을 미치지 않아야합니다. 또한 세 가지 가능한 선택 중 하나가 완전히 임의적이므로 복사 할 때 부모 개체가 어떻게 처리되어야하는지 결정해야합니다. 그래서 대부분의 경우 개체를 복사하는 것은 의미가 없으며 너무 오류가 발생하기 쉽습니다.
예를 들어, copy-and-swap idiom을 사용하십시오.
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
함수를 다시 구현해야합니다.
'QObject' 기반 클래스를 메타 타입으로 등록해야 할 때 어떤 상황이라도 제공 할 수 있습니까? 문서는 괜찮습니다. –
QObject 또는 그 하위 클래스를 qRegisterMetaType에 등록 할 필요가 없습니다. – vahancho
'qRegisterMetaType'은 QObject –