QVector::append() and copy-constructor
-
Can anybody explain why copy-constructor is being called twice here?
MyClass.h
#include <QDebug> class MyClass { public: MyClass(int a) : mA(a) { qDebug() << "parameterized constructor"; } MyClass() { qDebug() << "default constructor"; } MyClass(const MyClass &other) { qDebug() << "copy-constructor" << other.mA; } private: int mA; };
main.cpp
#include <MyClass.h> ... MyClass myclass(10); QVector<MyClass> qvec; qvec.append(myclass); ...
Output:
parametrized constructor copy-constructor 10 copy-constructor 19182872
-
Hi
qvec.append(myclass);
This will copy it to the one/new spot in the list
First new spot in list is created , then your class is copied to it.for std::vector they made emplace to solve that
http://www.cplusplus.com/reference/vector/vector/emplace/we say its constructed in place and hence no copy is needed.
I do not know if QVector can do the same.
-
@dream_captain
i dont know what happens... but i noticed.
if i call constructor for exampleMyClass myclass(10); QVector<MyClass> qvec; qvec.push_back(MyClass(myclass)); parameterized constructor copy-constructor 10 copy-constructor 1960650240 copy-constructor 10419688
MyClass myclass(10); std::vector<MyClass> qvec; qvec.push_back(myclass); parameterized constructor copy-constructor 10
-
@dream_captain: If your class is movable [1], than you can use std::move from C++11 to optimize:
int main() { MyClass myclass(10); QVector<MyClass> qvec; qvec.append(std::move(myclass)); }
which gives the following output:
parameterized constructor copy-constructor 10
VoilĂ :)
Note that the most Qt types are implicitely shared, so even calling the copy constructor is very cheap for them (effects for example QStringList::append())
[1] https://stackoverflow.com/questions/3106110/what-are-move-semantics
-
Hi,
Because when you add custom copy constructor you "destroy" the implicitly created move constructor/copy assignment operator.
Modify your class like that:
class MyClass { public: MyClass(int a) : mA(a) { qDebug() << "parameterized constructor"; } MyClass() : mA(0) { qDebug() << "default constructor"; } MyClass(const MyClass &other) : mA(other.mA) { qDebug() << "copy-constructor" << mA; } MyClass(MyClass &&) = default; MyClass & operator= (const MyClass &) = default; private: int mA; };
And you should be good again.
-
@SGaist it doesn't work with old visual studio 2012 compiler and Qt 5.5.1, but works well with vs2015 and qt 5.8.0. Seems like std::move support in msvc2012 is an issue.
-
Related issue: https://bugreports.qt.io/browse/QTBUG-49250