Unsolved saving a custom Unit* class
-
I implemented the stream operators >> and << and still I can't save the qobject pointer into the file settings. I don't know why. what else do you need to dig for the problem ?
and thanks for the note
-
Can you share your operators implementation ?
-
why I can't save a pointer qproperty like Unit*.
that's what the error says
QVariant::save: unable to save type 'Unit*' -
I don't know since you didn't share the complete code. Anyway, here is a dummy implementation that shows how it works:
class MyObject : public QObject { public: MyObject(QObject *parent = 0) : QObject(parent) {} QString foo() const { return _foo; } void setFoo(const QString& foo) { _foo = foo; } private: QString _foo; }; QDataStream &operator<<(QDataStream &ds, MyObject *object) { ds << object->foo(); return ds; } QDataStream &operator>>(QDataStream &ds, MyObject *object) { QString foo; ds >> foo; object->setFoo(foo); return ds; } QDebug operator<<(QDebug dbg, MyObject *object) { dbg << object->metaObject()->className() << object->foo(); return dbg; } Q_DECLARE_METATYPE(MyObject *) int main(int argc, char *argv[]) { QApplication app(argc, argv); qRegisterMetaType<MyObject *>(); qRegisterMetaTypeStreamOperators<MyObject *>(); MyObject *object = new MyObject; object->setFoo("myfoo"); QBuffer buffer; buffer.open(QBuffer::WriteOnly); QDataStream ds(&buffer); ds << object; buffer.close(); // later buffer.open(QBuffer::ReadOnly); ds.setDevice(&buffer); MyObject *object2 = new MyObject; ds >> object2; qDebug() << object2; delete object; delete object2; return 0; }
-
I'm trying to define the operators >> and << for a custom class called Unit, and I need to store a pointer.
here is how I define the functions
QDataStream &operator<<(QDataStream &out, const Unit *unit)
{
out << unit->value();
return out;
}QDataStream &operator>>(QDataStream &in, Unit *unit)
{
double value;
in >> value;
unit->setUserValue(value);
return in;
}void Unit::setUserValue(const qreal userValue)
{
qDebug() << "setUserValue" << this->userValue() << userValue << QString::number(m_unit,2);
if (this->userValue() == userValue)
return;if(isDefault()) m_value = userValue; else m_value = UnitManager::convertFrom(userValue,m_unit); qDebug() << "Value" << m_value; emit userValueChanged(); setDirty(RamDirty);
}
qRegisterMetaType<Unit*>();
qRegisterMetaTypeStreamOperators<Unit *>();
I'm getting the following compilation error messageerror: no match for 'operator>>' (operand types are 'QDataStream' and 'Unit*')
and also an error here/usr/include/qt/QtCore/qmetatype.h:771: error: invalid initialization of non-const reference of type 'quint8& {aka unsigned char&}' from an rvalue of type 'quint8 {aka unsigned char}'
stream >> static_cast<T>(t);
^
I also defined the meta typeQ_DECLARE_METATYPE(Unit)
Q_DECLARE_METATYPE(Unit*) -
Unit is a QObject base class you shouldn't call
Q_DECLARE_METATYPE
on it.Where are you doing the declaration and registrations ?
-
I'm doing it in main()
-
Something's wrong with your streaming operations, you don't save and load the same formats you use for your class. You have qreal on one side then double on another side.
You should really be precise when doing such operations.
-
I'm still getting the following error
/usr/include/qt/QtCore/qmetatype.h:771: error: no match for 'operator>>' (operand types are 'QDataStream' and 'Unit') stream >> *static_cast<T*>(t); ^
QDataStream &operator<<(QDataStream &out, const Unit *&unit) { out << unit->value(); return out; } QDataStream &operator>>(QDataStream &in, Unit *&unit) { qreal value; in >> value; unit->setUserValue(value); return in; }
In MAIN I define
qRegisterMetaType<Unit*>(); qRegisterMetaTypeStreamOperators<Unit *>(); ```in the header of Unit.h I define
Q_DECLARE_METATYPE(Unit*)
Q_DECLARE_METATYPE(Unit) -
@AndreAhmed said:
/usr/include/qt/QtCore/qmetatype.h:771: error: no match for 'operator>>' (operand types are 'QDataStream' and 'Unit')
stream >> static_cast<T>(t);Follow the compiler's error description! You're trying to save an instance of the class (i.e. an object), then you provide operators for saving a pointer to that class ... the compiler can't match one to the other.
QDataStream &operator>>(QDataStream &out, Unit *&unit)
is quite different from:
QDataStream &operator>>(QDataStream &out, Unit &unit) //< This is what you're invoking with stream >> *static_cast<Unit*>(t);
Additionally, don't pass pointer references, unless you intend on changing them ... this could have unforeseen consequences if in the implementation you do something along the lines of:
unit = nullptr;
for example.
Best is to even make a further step (although it's often considered quite over-protective) and make sure the pointer will not be moved, not only that it's pointing to a const object:
QDataStream &operator<<(QDataStream &out, const Unit * const unit) //< Forbid moving the pointer inside the implementation, not only modifying the object { } QDataStream & operator >> (QDataStream & in, Unit * const unit) //< Again, the pointer is constant, can't be modified, the object is not though { }