2012-09-30 87 views
3

衆所周知,Q_OBJECT是實例,不可複製。Q_OBJECT「複製」 - 複製所有屬性

是否有任何類型的語法糖來複制任意QObject派生類的所有靜態和動態屬性?

看來這是一個nobrainer,但我找不到任何這樣的參考 - 顯然實施一個自己應該是​​相當平凡 - 環路metaObject(),環路dynamicPropertyNames(),相應地設置。

+1

結束許多'metaObject()'你想循環嗎?我認爲子類的元對象會告訴你這個對象/類的所有*(包括繼承的)元屬性。這就是爲什麼我們實際上需要QMetaObject的偏移方法,如果我們只需要「額外」屬性的話。 – leemes

回答

5

您可以按如下方式實現副本助手類。

/** Enable QObjects to be explicitly copyable by copying property values. */ 
template<class T> 
class QObjectCopyHelper<T> 
{ 
protected: 
    explicit QObjectCopyHelper(T *client) : m_client(client) {} 

public: 
    T *clone(QObject *parent = 0) { 
     T *copy = new T(parent); 

     // loop over and copy properties from m_client to copy 
     // (both from T::staticMetaObject and dynamic ones) 

     return copy; 
    } 

private: 
    T *m_client; // <-- I think we need this, but I might be wrong 
}; 

然後你就可以與需要做非常低的工作,在任何QObject的子類使用此:

class MyClass : public QObject, public QObjectCopyHelper<MyClass> 
{ 
    Q_OBJECT 
    ... 
}; 

然而,這仍然需要clone()被調用(醜陋的「Java風格」) 。因此,我們可以額外定義一個只需調用clone()的拷貝構造函數,您也可以考慮在賦值運算符中調用assign()方法。

請注意,這真的只複製屬性!在QObject中跟蹤很多其他事物,就像當前的連接一樣。他們明確禁止複製QObject,因爲定義規則應該如何完成是非常困難的,這些規則對於某些用例而言是正確的,而在其他規則中則需要其他規則...

+0

是的,這就是我最終做的。但是,我猜想有2-3個不同的QObjectCopyStaticPropertiesHelper,QObjectCopyConnectionsHelper等等,可以讓我們使用任意規則組合。 – qdot

+0

@qdot噢,非常好的主意!關於我在代碼中需要的「m_client」指針的最後一句話:另一種方法是調用clone(this)而不是clone(),並使用提供的指針作爲源對象。這避免了另一個成員,從而減少了內存開銷。我認爲我們不能放棄指針,因爲我們不能在助手類中向'T *'施加'this'。但是我可能在這裏錯了,如果有人知道它更好,我會很開心的! ;) – leemes

2

一個解決方案被討論here,他們採取循環的屬性方法。這裏似乎沒有「語法糖」。