How to append struct to QList?
-
Hi
Is there a more elegant way to append a custom struct data type to a QList?
Lets say I have this custom struct and declared QList of that same type:struct Blood{ QDateTime dateTime; unsigned int systole; unsigned int diastole; unsigned int puls; }; ... private: QList<Blood> readDataList;
Now I want to append new values to the list (by going through a SQL source), I did this:
Blood tempValue; while (query.next()) { tempValue.dateTime = QDateTime::fromString(query.value(0).toString(), "dd.MM.yyyy-hh:mm"); tempValue.systole = query.value(1).toInt(); tempValue.diastole = query.value(2).toInt(); tempValue.puls = query.value(3).toInt(); readDataList.append(tempValue); }
this works, but is there a shorter way doing this? Something like this in one line without tempValue?:
readDataList.append(Blood(QDateTime::fromString(query.value(0).toString(), "dd.MM.yyyy-hh:mm") ,query.value(1).toInt(),query.value(2).toInt(),query.value(3).toInt());
-
@pauledd said in How to append struct to QList?:
Basically you can see astruct
as aclass
(just with different default visibility).
So you are able to add methods and also a constructor to the struct.struct Blood{ Blood(QDateTime dt, unsigned int s, unsigned int d, unsigned int p) : dateTime(dt), systole(s), diastole(d), puls(p) { } QDateTime dateTime; unsigned int systole; unsigned int diastole; unsigned int puls; }; .... readDataList << Blood(QDateTime::fromString(query.value(0).toString(), "dd.MM.yyyy-hh:mm") ,query.value(1).toInt(),query.value(2).toInt(),query.value(3).toInt();
-
Your class should be assignable to go in a QList:
To qualify, a type must provide a default constructor, a copy constructor, and an assignment operator.
I think in your case they are created by the compiler but it probably is a good idea to make them explicit together with a
Blood(const QDateTime& dt, unsigned int s, unsigned int d, unsigned int p)
constructor as suggested above -
@pauledd said in How to append struct to QList?:
@VRonin and why you only use const & with the QDateTime and not with the int's too?
My general rule is: if the data is greater than 64 bits, pass it by const reference.
QDateTime might be borderline as inside it probably just contains a quint64 but I pass it by const reference to be safe, the ints are (normally) 32 bits so they can go by value with no expense
-
@pauledd said in How to append struct to QList?:
why you only use const & with the QDateTime and not with the int's too?
because you wont gain any/much benefit (efficiency) from it. With the const reference you save one copy instruction.
-
Just one more question arose
@VRonin said in How to append struct to QList?:
To qualify, a type must provide a ... and an assignment operator.
Does the assignment operator look correct? (it compiles fine):
struct Blood{ Blood(const QDateTime& dt, unsigned int s, unsigned int d, unsigned int p) :dateTime(dt),systole(s),diastole(d),puls(p){} Blood(){} QDateTime dateTime; unsigned int systole; unsigned int diastole; unsigned int puls; friend QDataStream &operator<<(QDataStream &out, const Blood& blood){ out << blood.dateTime << blood.systole << blood.diastole << blood.puls; return out; } };
-
That's not an assignment operator. see http://www.cplusplus.com/doc/tutorial/classes2/#copy_assignment
class Blood{ public: Blood(const QDateTime& dt, unsigned int s, unsigned int d, unsigned int p) :dateTime(dt),systole(s),diastole(d),puls(p){} Blood() {} //Default constructor Blood(const Blood& other) :dateTime(other.dateTime ),systole(other.systole),diastole(other.diastole),puls(other.puls){} // Copy constructor Blood& operator=(const Blood& other){ dateTime = other.dateTime ; systole=other.systole; diastole=other.diastole; puls=other.puls; return *this; } //assingment operator // encapsulate members const QDateTime& dateTime() const { return dateTime;} void setDateTime(const QDateTime& val){dateTime=val;} unsigned int systole() const { return systole;} void setSystole(unsigned int val){systole=val;} unsigned int diastole() const { return diastole;} void setDiastole(unsigned int val){diastole=val;} unsigned int puls() const { return puls;} void setPuls(unsigned int val){puls=val;} private: QDateTime dateTime; unsigned int systole; unsigned int diastole; unsigned int puls; };
-
More questions :(
My little nice struct exploded to a huge class ;) that makes me considering to use my very first approach again.
I just short read about assignment operator and in your assignment operator declaration shouldn't there also be a self-assigned test like this?
... if (this == &other) return *this; ...
If I try your class I get a load of errors about previous declarations:
In file included from ../test1/blood.cpp:1:0: ../test1/blood.h:31:12: error: 'QDateTime Blood::dateTime' conflicts with a previous declaration QDateTime dateTime; ^ ../test1/blood.h:21:18: note: previous declaration 'const QDateTime& Blood::dateTime() const' const QDateTime& dateTime() const { return dateTime;} ^ ../test1/blood.h:32:15: error: 'unsigned int Blood::systole' conflicts with a previous declaration unsigned int systole; ^ ../test1/blood.h:23:14: note: previous declaration 'unsigned int Blood::systole() const' unsigned int systole() const { return systole;} ^ ../test1/blood.h:33:15: error: 'unsigned int Blood::diastole' conflicts with a previous declaration unsigned int diastole; ^ ../test1/blood.h:25:14: note: previous declaration 'unsigned int Blood::diastole() const' unsigned int diastole() const { return diastole;} ^ ../test1/blood.h:34:15: error: 'unsigned int Blood::puls' conflicts with a previous declaration unsigned int puls; ^ ../test1/blood.h:27:14: note: previous declaration 'unsigned int Blood::puls() const' unsigned int puls() const { return puls;} ^ ../test1/blood.h: In constructor 'Blood::Blood(const QDateTime&, unsigned int, unsigned int, unsigned int)': ../test1/blood.h:8:4: error: class 'Blood' does not have any field named 'dateTime' :dateTime(dt),systole(s),diastole(d),puls(p){} ^ ../test1/blood.h:8:17: error: class 'Blood' does not have any field named 'systole' :dateTime(dt),systole(s),diastole(d),puls(p){} ^ ../test1/blood.h:8:28: error: class 'Blood' does not have any field named 'diastole' :dateTime(dt),systole(s),diastole(d),puls(p){} ^ ../test1/blood.h:8:40: error: class 'Blood' does not have any field named 'puls' :dateTime(dt),systole(s),diastole(d),puls(p){} ^ ../test1/blood.h: In copy constructor 'Blood::Blood(const Blood&)': ../test1/blood.h:11:2: error: class 'Blood' does not have any field named 'dateTime' :dateTime(other.dateTime ),systole(other.systole),diastole(other.diastole),puls(other.puls){} // Copy constructor ^ ../test1/blood.h:11:28: error: class 'Blood' does not have any field named 'systole' :dateTime(other.dateTime ),systole(other.systole),diastole(other.diastole),puls(other.puls){} // Copy constructor ^ ../test1/blood.h:11:51: error: class 'Blood' does not have any field named 'diastole' :dateTime(other.dateTime ),systole(other.systole),diastole(other.diastole),puls(other.puls){} // Copy constructor ^ ../test1/blood.h:11:76: error: class 'Blood' does not have any field named 'puls' :dateTime(other.dateTime ),systole(other.systole),diastole(other.diastole),puls(other.puls){} // Copy constructor ^ ../test1/blood.h: In member function 'Blood& Blood::operator=(const Blood&)': ../test1/blood.h:13:10: error: invalid use of member function (did you forget the '()' ?) dateTime = other.dateTime ; ^ ../test1/blood.h:14:8: error: invalid use of member function (did you forget the '()' ?) systole=other.systole; ^ ../test1/blood.h:15:9: error: invalid use of member function (did you forget the '()' ?) diastole=other.diastole; ^ ../test1/blood.h:16:5: error: invalid use of member function (did you forget the '()' ?) puls=other.puls; ^ ../test1/blood.h: In member function 'const QDateTime& Blood::dateTime() const': ../test1/blood.h:21:44: error: invalid initialization of reference of type 'const QDateTime&' from expression of type '<unresolved overloaded function type>' const QDateTime& dateTime() const { return dateTime;} ^ ../test1/blood.h: In member function 'void Blood::setDateTime(const QDateTime&)': ../test1/blood.h:22:48: error: invalid use of member function (did you forget the '()' ?) void setDateTime(const QDateTime& val){dateTime=val;} ^ ../test1/blood.h: In member function 'unsigned int Blood::systole() const': ../test1/blood.h:23:39: error: cannot convert 'Blood::systole' from type 'unsigned int (Blood::)() const' to type 'unsigned int' unsigned int systole() const { return systole;} ^ ../test1/blood.h: In member function 'void Blood::setSystole(unsigned int)': ../test1/blood.h:24:42: error: invalid use of member function (did you forget the '()' ?) void setSystole(unsigned int val){systole=val;} ^ ../test1/blood.h: In member function 'unsigned int Blood::diastole() const': ../test1/blood.h:25:40: error: cannot convert 'Blood::diastole' from type 'unsigned int (Blood::)() const' to type 'unsigned int' unsigned int diastole() const { return diastole;} ^ ../test1/blood.h: In member function 'void Blood::setDiastole(unsigned int)': ../test1/blood.h:26:44: error: invalid use of member function (did you forget the '()' ?) void setDiastole(unsigned int val){diastole=val;} ^ ../test1/blood.h: In member function 'unsigned int Blood::puls() const': ../test1/blood.h:27:36: error: cannot convert 'Blood::puls' from type 'unsigned int (Blood::)() const' to type 'unsigned int' unsigned int puls() const { return puls;} ^ ../test1/blood.h: In member function 'void Blood::setPuls(unsigned int)': ../test1/blood.h:28:36: error: invalid use of member function (did you forget the '()' ?) void setPuls(unsigned int val){puls=val;} ^ ../test1/blood.cpp: At global scope: ../test1/blood.cpp:3:1: error: redefinition of 'Blood::Blood()' Blood::Blood() ^ In file included from ../test1/blood.cpp:1:0: ../test1/blood.h:9:2: note: 'Blood::Blood()' previously defined here Blood() {} //Default constructor ^ Makefile:885: recipe for target 'blood.o' failed
-
@pauledd said in How to append struct to QList?:
If I try your class I get a load of errors about previous declarations:
You should resolve the errors, it's a trivial typo (conflicting function and member names):
class Blood { public: // ... QDateTime dateTime() const; void setDateTime(const QDateTime &); //... private: DateTime _dateTime; //< Rename so it doesn't conflict with the method name // ... }; //< Good practice is to be explicit about inlined methods and makes for a lighter reading //< Also my advice is to return by value, not const references inline QDateTime Blood::dateTime() const { return _dateTime; } inline void Blood::setDateTime(const QDateTime & val) { _dateTime = val; }