Sorry for this stupid question, but I can't find an answer by myself, I'm too new in C++ :(
class DBObject : public QObject
{
...
protected:
virtual QString tableName() = 0;
};
class DBUserObject : public DBObject
{
...
protected:
virtual QString tableName() { return "profiles"; };
};
And I have this code in parent:
DBObject::DBObject(quint32 id)
: QObject(0)
{
...
if (id != 0)
load(id);
}
bool DBObject::load(quint32 id)
{
QString query = QString("select %1 from %2 where id = :id")
.arg(fieldList().join(","))
.arg(tableName()); <--- here is trouble
...
}
So I'm trying to execute:
DBUserObject user(3);
But in result I have a runtime error. Why not "profiles"?
Based on the OP's followup comment:
DBUserObject user(3). It is loading item in its constructor.
If you mean the DBObject constructor (and not the DBUserObject constructor), then there's your problem. Virtual functions do not work inside constructors. Constructors run from the least-derived (most base) class to the most-derived (actual type) class. When a class' constructor runs, the object is only of that class' type, and nothing more derived.
In other words, when you create a DBUserObject, first the QObject constructor runs, and inside that constructor the object is only a QObect and nothing more. Then, the DBObject constructor runs, and inside that constructor the object is only a DBObject and nothing more. Finally, the DBUserObject constructor runs and the object is finally a DBUserObject.
So if you call load() inside of the DBObject constructor, the object is only a DBObject at that point and so has only the DBObject version of load. This applies similarly for any virtual function.
If you want to get the effect of calling the DBUserObject version of load(), you will need to call it from the DBUserObject constructor, or from outside the class after the object has been constructed.
More information:
The problem is most probably not in the code you provided. Are you slicing the DBObjects? That could happen if you pass by value into a function, or if you store inside a container directly (not through a pointer).
Another thing is why is the tableName() not pure-virtual in your base class?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With