[SOLVED] When can I use Q_DECLARE_TYPEINFO() with Q_MOVABLE_TYPE ?
-
According to "nice article at doobs":http://www.drdobbs.com/c-made-easier-plain-old-data/184401508 , we should not use memcpy() when copying a object that has constructor or destructor(std::string was the good example in that article). But I found following statements in Qt doc
@
// Example of a movable type:
class Point2D
{
public:
Point2D() { data = new int[2]; }
Point2D(const Point2D &other) { ... }
~Point2D() { delete[] data; }Point2D &operator=(const Point2D &other) { ... } int x() const { return data[0]; } int y() const { return data[1]; }
private:
int *data;
};Q_DECLARE_TYPEINFO(Point2D, Q_MOVABLE_TYPE);
@The Point2D class has constructor and destructor but can we use memcpy(or memmove) with it?
the
@int* data@
member seems to be heap allocated and assignment operator could do deep-copy it.
According to Qt doc, it sounds like we can use following decl for std::string.@
namespace std {
Q_DECLARE_TYPEINFO(string, Q_MOVABLE_TYPE);
}
@Little bit confused. is it ok for me to do that for std::string?
Might be Qt doc say that 'moving'(NOT 'copying') is ok in this case.
-
memcpy() can be a bit misleading here, as it is a matter of definition whether an object is copied (the object at const void* source is still valid after the operation) or moved (the object at const void* source is no longer valid after the operation).
There is no such thing as memory beeing moved; it is always a copy operation with the former memory region beeing declared invalid. The difference between memcpy() and memmove() is that memmove() can be use to copy overlapping memory regions (at a performance cost compared to memcopy()), but both copy.
A Q_MOVABLE_TYPE can be moved using memcpy() (instead of the copy constructor), but not necessarily copied.
A Point2D object can be freely moved in memory using memcpy(), as int *data still points to a valid memory region. It cannot be, however, copied using memcpy(), as both int *data would point to the same memory region.
Whether this is true for std::string purely depends on the implementation of std::string in the used standard library, it might be, but it also might not be. This is why the Q_MOVABLE_TYPE type info is usually set by the author of the class in question, not the user.
QString is, as all implictly shared classes, a Q_MOVABLE_TYPE.
Be aware that there is a difference between movable as in move semantics in terms of providing a move constructor and move assignment operator and movable in terms of beeing able to be moved using memcpy(); this is why it is mentioned in the documentation.
-
Non-movable classes are for instance any classes which use a "Q-Pointer":http://techbase.kde.org/Policies/Library_Code_Policy#Q-Pointers, like QObject, as moving would lead to a dangling Q-Pointer.