2010-05-18 101 views
5

我知道Qobjects應該是身份而不是值,例如,您不能複製它們,默認情況下,複製構造函數和賦值被禁用,如qt文檔中所述。但是有可能使用克隆方法從現有的QObject創建一個新的QObject?這會是一個邏輯錯誤嗎? 如果我說QObject克隆

QObject b; 
QObject a; 
b.cloneFrom(a); 

QObject a = new QOBject(); 
QObject b = new QOBject(); 
b->cloneFrom(a); 

和克隆方法複製的東西一樣成員等會這樣錯了嗎?

如果這是好的我可以寫我自己的拷貝構造函數和賦值操作符嗎?

注意:我實際上想用繼承qobject的類來試試這個。

+0

這也會克隆連接沒有?恕我直言,你的代碼有什麼問題......你可以用POD結構重新做這件事嗎? – elcuco 2010-05-18 08:22:06

+0

不,不需要克隆只是在對象中設置的數據成員(主要是由繼承層添加的數據成員)。 – Olorin 2010-05-18 08:28:46

回答

7
在我看來克隆的QObject

幾乎總是語義破裂,導致不必要的副作用,因爲他們有一個「身份」,正如你已經說過的。因此,克隆打破了QObject的所有假設,比如它們的信號/插槽連接和動態屬性。您應該考慮克隆的對象是否真的需要QObject,或者您想克隆的「數值部分」是否可以分解出來。

而且,如果有的話,克隆只對QObject的特定子類有意義,而不適用於QObjects本身(它們沒有真正的「類似於值的」屬性)。另外,A;

也,A; B; A.cloneFrom(B)看起來破損,因爲如果B是B的一個子類的實例而不是B本身,則它不起作用。 克隆應該通過一個虛擬的B * B :: clone()const來完成。

+3

我必須補充一點,一個常見的設計錯誤是將所有東西都做成QObject,而不是在做之前先考慮兩次。我只在必要時製作QObjects,即適用「身份」模式的地方,我需要信號/插槽等。 – 2010-05-18 09:49:14

+0

完全同意弗蘭克。即使Qt本身也包含很多不是從QObject派生的類。所有值容器如QString,QList,QDomNode ...它們不是從QObject派生的。 – VestniK 2010-05-18 10:17:26

+0

我不好當我寫代碼給我QObject作爲一個例子增值業務實際上並不是qobject類型,但派生類型的代碼應該是MyClass a,b; b.cloneFrom(a);但我認爲 我會考慮使用不是從qobject派生的類 – Olorin 2010-05-18 14:17:45

4

我認爲在這種情況下最好的做法是用你想在QObject之間複製的數據創建類。這個類不應該從QObject或派生自QObject的任何類派生。而這個班級將是「價值容器」。在這種情況下,您應該能夠以非常好的方式解決您的問題。

一個提示:對於這個類,你可以使用隱式數據共享與寫時複製,以減少不必要的複製開銷:http://doc.qt.io/qt-5/implicit-sharing.html