2014-09-17 7 views
3

Here 우리는 복사 구성 및 복사 할당 연산자를 평가할 수 없음을 읽을 수 있습니다. 그러나 here 우리는 qRegisterMetaTypeQ_DECLARE_METATYPE에 public 기본 생성자, 공용 복사본 생성자 및 공용 소멸자가 있어야한다는 것을 알 수 있습니다. 문제는 누가 거짓말을하고 있는가? 아니면 제대로 이해하지 못했습니까?QObject의 하위 클래스에 대한 복사 생성자가 있습니까?

+0

'QObject' 기반 클래스를 메타 타입으로 등록해야 할 때 어떤 상황이라도 제공 할 수 있습니까? 문서는 괜찮습니다. –

+0

QObject 또는 그 하위 클래스를 qRegisterMetaType에 등록 할 필요가 없습니다. – vahancho

+0

'qRegisterMetaType'은 QObject –

답변

4

모든 것이 사실임 :
1. QObject은 복사 할 수 없으며 모든 자손도 복사 할 수 없습니다.
2. Q_DECLARE_METATYPE은 public 생성자, 복사 생성자 및 소멸자가있는 객체를 허용합니다.

QObject 자손을 Q_DECLARE_METATYPE으로 등록 할 수 없기 때문에 모순이 없습니다. 당신이 QVariant에 클래스를 변환 할 때

그것은 개체의 복사본을 만들기 위해 복사 생성자를 사용합니다 : EDIT

void *ptr = QMetaType::construct(x->type, copy); 
+0

하지만 QObject처럼 작동하도록 클래스에 복사 생성자가 있어야하는 이유는 무엇입니까? 나는 QVariant에 저장하는 것을 의미합니다. – VALOD9

+3

QObject, QWidget ...을'QVariant'에 ​​저장할 수 없기 때문에'QVariant' 클래스에 복사 생성자가 있어야하지만 QObject처럼 작동하지 않습니다 – Ezee

+0

복사 생성자에 대한 설명이 추가되었습니다 답에. – Ezee

1

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에서 파생되는 클래스의 복사 생성자와 대입 연산자를 구현할 수

0

등으로 구성 복사 할 수 있습니다 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 함수를 다시 구현해야합니다.