2011-07-23 81 views
6

由於the QObject documentation和許多其他人解釋,QObject有一個身份,從而隱藏其複製構造函數和賦值運算符。C + + Qt反射與複製和分配

但是,我不是從QObject得到它的動態屬性功能或信號/插槽功能。我只想反射,或訪問Foo::staticMetaObject的能力。

class Foo : public QObject { 
    Q_OBJECT 
    Q_ENUMS(Color) 
public: 
    enum Color { Blue, Red, Pink }; 
private: 
    Color color; 
}; 

Q_DECLARE_METATYPE(Foo::Color) 

我再不能複製Foo有:

Foo a; 
Foo b; 
a = b; 

什麼是允許在這種情況下副本和任務的最佳方法是什麼?我絕對需要寫一個拷貝構造函數和賦值操作符嗎?他們看起來像什麼?反射仍然有效嗎?

+0

你的意思是說,不使用'QObject'。因爲反思並不是問題的根源在這裏。問題是QObject使複製和分配私有(有一個很好的理由)。 –

+1

@kristianp,很好的建議,我會編輯*如果@alexisdm沒有提供確切的答案給我的確切問題。通常情況下,答案是「不要做你要做的事情」,但在這種情況下,即使這是一個合理的答案,也有一個讓我做我想做的事情:'Q_GADGET' –

回答

14

如果你只對具有

  • 類名反射興趣,
  • 枚舉和標誌(Q_ENUMS,Q_FLAGS)
  • 類信息(Q_CLASSINFO

您可以使用Q_GADGET instead of Q_OBJECT

class Foo { 
    Q_GADGET 
    Q_ENUMS(Color) 
public: 
    enum Color { Blue, Red, Pink }; 
private: 
    Color color; 
}; 

它將聲明並定義Foo::staticMetaObject

+0

哇,我之前沒有從'Q_GADGET'聽到。所以它似乎是'Q_OBJECT'的輕量級和靜態版本,在某些情況下可能非常有用(如此)。傷心它沒有記錄,至少我找不到它。這使得它非官方的,因此不能保證在未來工作:( – leemes

+0

@leemes它實際上簡單地提到'QObject'頁面上的'Q_OBJECT'旁邊(我添加了上面的鏈接)。但是你可以說它隱藏得很好,而我在通過moc源代碼搜索其他東西時才發現它。 – alexisdm

1

我對qt瞭解不多,但是如果不允許使用複製構造函數,那麼應該有一個原因(在你發佈的鏈接中討論過)。你可以改變你的設計而不是擁有它。

如果你堅持,那麼memcpy仍然是你的最後手段。我個人不推薦它,因爲你必須關心深度複製,vtable等,這些並不總是微不足道的。

2

您當然可以在派生類中實現複製構造函數和複製賦值運算符,但這可能是糟糕設計的一個標誌。拿這個例子:

#include <iostream> 

class Base { 
public: 
    Base() {} 

private: 
    Base(const Base& other) { 
     std::cout << "Base copy constructor invoked!" << std::endl; 
    } 
}; 

class Derived : public Base { 
public: 
    Derived() {} 

    Derived(const Derived& other) { 
     std::cout << "Derived copy constructor invoked!" << std::endl; 
    } 
}; 

int main(int argc, char** argv) { 
    Derived a; 
    Derived b = a; 

    return 0; 
} 

這會編譯得很好。但是,如預期的那樣,當您運行生成的程序時,所有打印的內容是Derived copy constructor invoked!。當基類將其拷貝構造函數/拷貝賦值運算符聲明爲私有時,這不會阻止派生類實現它們自己的版本。它只是可以防止派生類調用基類版本

其中存在的問題是:確保您複製對象的所有部分以確保您確實擁有兩個不同的副本總是一個很好的做法。部分對象包含基類擁有的數據,所以您應該始終確保調用基類的拷貝構造函數/拷貝賦值操作符以確保完成拷貝。但是這些數據在設計上是不可複製的。因此,不可能複製對象的所有部分。

如果你想堅持這個設計,這取決於你。要問自己的一個重要問題是,你的派生類是否真的需要可複製?如果沒有,那麼沒有什麼可擔心的!