PDA

View Full Version : Qt Container do not save items



Andre008
23rd February 2016, 20:20
Hello,

i try to model the relationshipe between Persons in a Group.

The code looks like this:


dialog.h


#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>

#include "group.h"
#include "person.h"


namespace Ui {
class Dialog;
}

class Dialog : public QDialog
{
Q_OBJECT

public:
explicit Dialog(QWidget *parent = 0);
~Dialog();

void test1();

private:
Ui::Dialog *ui;
};

#endif // DIALOG_H



dialog.cpp



#include "dialog.h"
#include "ui_dialog.h"

Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);

test1();


}

Dialog::~Dialog()
{
delete ui;
}

void Dialog::test1()
{
//create a group
Group group;

//create two persons
Person pete = group.addPersonToGroup("Pete");
Person mary = group.addPersonToGroup("Mary");

// create relationship
group.knows(pete,"friends",mary);

//if the debugger run to this point,
// the member variable mFriends. is empty
// i have expected:
// pete.mFriends contains mary
// mary.mFriends contains pete
int i = 0;
}



group.h


#ifndef GROUP_H
#define GROUP_H

#include <QString>

#include "person.h"

class Group
{
public:
Group();
Person addPersonToGroup(QString name);
void knows(Person p1, QString label, Person p2);
};

#endif // GROUP_H




group.cpp


#include "group.h"

Group::Group()
{
}

Person Group::addPersonToGroup(QString name)
{
Person newPerson;
newPerson.setName(name);

return newPerson;
}

void Group::knows(Person p1, QString label, Person p2)
{

p1.knows(label, p2);
}



person.h


#ifndef PERSON_H
#define PERSON_H

#include <QString>

#include "personset.h"


class PersonSet;

class Person
{
public:
Person();

void setName(QString name);
void knows(QString label, Person p1);

private:
QString mName ;
QHash<QString,PersonSet> mFriends;
};

#endif // PERSON_H




person.cpp


#include "person.h"

Person::Person()
{
}

void Person::setName(QString name)
{
mName = name;
}

void Person::knows(QString label,Person p1)
{
PersonSet personSet = mFriends[label];

if(personSet.empty())
{
// here is the insert of person into mFriends/ QHash
personSet.insert(0,p1);
mFriends.insert(label,personSet);
}

personSet.insert(0,p1);

if(!label.startsWith("_back_"))
{
p1.knows("_back_"+label,*this);
}
}


int
personSet.h


#ifndef PERSONSET_H
#define PERSONSET_H

#include <QHash>

#include "person.h"

class Person;

class PersonSet : public QHash<int,Person>
{
public:
PersonSet();
};

#endif // PERSONSET_H



personSet.cpp


#include "personset.h"

PersonSet::PersonSet()
{
}


Like descripted in the conments of the function Dialog::test1(), the mFriends variable of the typ personSet container class which inherits from QHash<int,Person> is empty after the function Dialog::test1() passes through.

But i do get it why ?

Thx

d_stranz
23rd February 2016, 22:32
But i do get it why ?

In this method:


void Group::knows(Person p1, QString label, Person p2)

you are passing all of the arguments by value, not by reference. This means that p1 and p2 are temporary copies of "pete" and "mary", not the actual "pete" and "mary" instances themselves. Inside the method, these temporary Person instances are made friends of each other, and as soon as the method exits, the temporaries go out of scope and they aren't friends any more :( In fact, they don't even exist. :( :( Your original instances of "pete" and "mary" are never modified, just their copies.

If you want this to work as you expect, you need to learn how passing arguments by reference works. Your code should look like this instead:


void Group::knows(Person & p1, const QString & label, Person & p2)

The "const QString &" declaration is good practice. The "const" tells the compiler that "label" won't be modified inside the method, and the pass by reference ("&") tells the compiler it doesn't need to copy "label", it just passes its address.

Andre008
24th February 2016, 00:36
This was the issue
Thx