C++和虚方法覆盖

sil*_*ent 2 c++ qt

抱歉这个愚蠢的问题,但我自己找不到答案,我在C++中太新了:(

class DBObject : public QObject
{
    ...
protected:
    virtual QString tableName() = 0;
};

class DBUserObject : public DBObject
{
    ...
protected:
    virtual QString tableName()  { return "profiles"; };
};
Run Code Online (Sandbox Code Playgroud)

我在父母中有这个代码:

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
    ...
}
Run Code Online (Sandbox Code Playgroud)

所以我正在尝试执行:

DBUserObject user(3);
Run Code Online (Sandbox Code Playgroud)

但结果我有一个运行时错误.为什么不"个人资料"?

Tyl*_*nry 15

根据OP的后续评论:

DBUserObject用户(3).它是在其构造函数中加载项.

如果你的意思是DBObject构造函数(而不是DBUserObject构造函数),那就是你的问题.虚函数在构造函数中不起作用.构造函数从最小派生(最基础)类运行到最派生(实际类型)类.当一个类的构造函数运行时,该对象只是该类的类型,而不再是派生的.

换句话说,当你创建一个DBUserObject,首先QObject构造函数运行,并且在该构造函数内部,对象只是一个QObect而不是更多.然后,DBObject构造函数运行,并且在该构造函数内,对象只是一个DBObject而已.最后,DBUserObject构造函数运行,对象最终是a DBUserObject.

因此,如果您load()DBObject构造函数内部调用,则该对象仅DBObject在该点处,因此仅DBObject具有加载版本.这同样适用于任何虚拟功能.

如果要获得调用DBUserObject版本的效果load(),则需要在DBUserObject构造对象之后从构造函数或类外部调用它.

更多信息: