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
    

  • Qt Champions 2016

    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 example

        MyClass 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


  • Lifetime Qt Champion

    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.

    See C++ move constructor and C++ copy assignment operator.



  • @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.


  • Lifetime Qt Champion

    Because VS2012 has incomplete C++11 support. See this page.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.