7

I know that Qobjects are supposed to be identities not values eg you cannot copy them and by default the copy constructor and assignment are disabled as explained in qt documentation. But is it possible to create a new QObject from an existing one using a clone method? Would this be a logic error ? If I say

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

or

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

and the clone method copies stuff like members etc would this be wrong?

And if this is ok can I write my own copy constructor and assignment operator that does just that?

Note: I actually want to try this with classes that inherit qobject.

Daniel Vérité
  • 58,074
  • 15
  • 129
  • 156
Olorin
  • 395
  • 1
  • 4
  • 12
  • This would also clone the connections no? IMHO, there is something wrong in your code... can you re-do this with POD structs? – elcuco May 18 '10 at 08:22
  • no the conections dont need to be cloned just the data members that are set in the object (mainly the ones added by the inheritance layer). – Olorin May 18 '10 at 08:28

2 Answers2

8

in my opinion cloning QObjects is almost always semantically broken and leads to unwanted side-effects, due to them having an "identity" as you already said. Therefore, cloning breaks all the assumptions one has about QObjects, like their signal/slot connections and dynamic properties. You should consider if the objects to clone really need to be QObjects, or if the "value-part" you want to have cloned could be factored out.

And if at all, cloning makes only sense for your specific subclasses of QObjects, not for QObjects themselves (which have no real "value-like" properties).

also, A; B; A.cloneFrom( B ) looks broken, as it doesn't work if B is instance of a subclass of B instead of B itself. Clone should be done via a virtual B* B::clone() const I'd say.

Frank Osterfeld
  • 24,815
  • 5
  • 58
  • 70
  • 3
    I have to add that a common design mistake is to make everything a QObject instead of thinking twice before doing so. I only make QObjects where necessary, i.e. where the "identity" pattern applies and I need signal/slots etc. – Frank Osterfeld May 18 '10 at 09:49
  • Totally agree with Frank. Even Qt itself contains a lot of classes which are not derived from QObject. All value containers like QString, QList, QDomNode ... they are not derived from QObject. – VestniK May 18 '10 at 10:17
  • My bad when i wrote the code i gave QObject as an example the vars are not actually of qobject type but of the derived type the code should have been MyClass a,b;b.cloneFrom(a); but i think i will consider using a class not derived from qobject – Olorin May 18 '10 at 14:17
6

I think that the best practice in this case to create class with the data you want to copy between QObjects. This class should not be derived from QObject or any class derived from QObject. And this class will be "value container". In this case you should be able to solve your problem in really good way.

One more tip: for this class you can use implicit data sharing with copy on write to reduce overhead of unnecessary copying: http://doc.qt.io/qt-5/implicit-sharing.html

Zitrax
  • 19,036
  • 20
  • 88
  • 110
VestniK
  • 1,910
  • 2
  • 17
  • 29