Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

[SOLVED] Container Classes - QVector problem



  • I have been pulling my hair on this one

    I have a QVector<UserStudio>, UserStudio being a custom object

    I am following this doc so that my Object can be copied in a Container
    but when I copy my QVector, I loose some attribute on my custom Object (attributes that are not primitive type). I have created a copy constructor, but no success. Anyone got this problem before? Thanks

    class Employee
    {
    public:
    	Employee() {}
    	Employee(const Employee &other);
    
    	Employee &operator=(const Employee &other);
    
    private:
    	QString myName;
    	QDate myDateOfBirth;
                PowerCurve powerCurve;  //Custom object that get lost during copy!
    };
    

    Here is my real class


  • Moderators

    Do you actually copy that member in the copy constructor of your class (you only attached a header so I can't say)?

    Does PowerCurve have a proper copy constructor? If not and it's not a POD then the compiler generated copy constructor of it will not do the right thing.

    I loose some attribute on my custom QObject

    What QObject? I don't see any in your code. In any case QObjects are not copyable.



  • I think you found the problem.
    The class "PowerCurve" is also a custom Object (not QObject, sorry)

    I have defined theses 2 constructors in Power Curve:

    PowerCurve();
    PowerCurve( const PowerCurve& other );
    

    For some reason, it uses the empty constructor and reset my PowerCurve object attribute when I copy the QVector<UserStudio>. Trying to find a good way to fix this because I need the empty constructor also for default values.

    Here are the full cpp
    UserStudio.cpp
    PowerCurve.cpp


    PowerCurve reset in action:
    Before (PowerCurve is set):

    for (int i=0; i<vecUserStudio.size(); i++) {
        UserStudio userStudio = vecUserStudio.at(i);
        qDebug() << "User Studio power Curve is_Main:" << userStudio.getPowerCurve().getFullName() << userStudio.getPowerCurve().getId() << "test att:" << userStudio.getDisplayName();
    }
    

    After Copying QVector (PowerCurve back to default..)

    for (int i=0; i<vecUserStudio.size(); i++) {
        UserStudio userStudio = vecUserStudio.at(i);
        qDebug() << "User Studio power Curve is_AfterCopy:" << userStudio.getPowerCurve().getFullName() << userStudio.getPowerCurve().getId() << "test att:" << userStudio.getDisplayName();
    }
    

    Log:
    User Studio power Curve is_Main: " Kinetic - Road Machine" 59 test att: "Max"
    User Studio power Curve is_AfterCopy: "- - TrainerNotSet" 0 test att: "Max"


    Here is how I update the PowerCurve in the QVector :

    UserStudio myUserStudio = vecUserStudio.at(riderID-1);
    
    myUserStudio.setUsingPowerCurve(true);
    myUserStudio.setCompanyID(company_id);
    myUserStudio.setBrandID(trainer_id);
    
    PowerCurve myCurve;
    myCurve.setId(trainer_id);
    myCurve.setName(companyName, trainerName);
    myCurve.setCoefs(coef0, coef1, coef2, coef3);
    myCurve.setFormulaInCode(formulaInCode);
    
    myUserStudio.setPowerCurve(myCurve);
    vecUserStudio.replace(riderID-1, myUserStudio);

  • Moderators

    You've got this in your copy constructor:

    this->powerCurve = other.powerCurve;
    

    but that is not calling a copy constructor PowerCurve::PowerCurve( const PowerCurve&). powerCurve is first default constructed and then you call an assignment operator (which you haven't specified so a compiler generates a bad one for you).

    If you want to use a copy constructor here then you need to use the initialization list like this:

    UserStudio::UserStudio( const UserStudio& other )
       : powerCurve(other.powerCurve), /* other fields ... */
    {}
    

    but I suggest you implement PowerCurve& PowerCurve::operator=(const PowerCurve&) anyway.

    There's a rule of thumb in C++ called rule of three : destructor, copy constructor, copy assignment operator - if you implement any of these you should probably implement all of them or bugs will follow.



  • Thanks for the help Chris,

    Finally the problem was just another function overwriting the PowerCurve, so not related with Copy Constructor, etc. I left the default copy constructor that are generated to save coding time, the Objects are just POD so the default is good for me.


Log in to reply