C++中虚方法的误解

Virtual method misconception in C++

我没有 OOP 经验。我正在使用 C++ 和 Qt 开发应用程序。我已经实现了 2 个 classes,一个是基础的,一个是从它继承的。然后我为两者添加了虚拟方法并且一切正常。但后来我意识到我不认为它应该......这是例子:

这是我的基地 class :

namespace Ui {
class CGenericProject;
}

class CGenericProject : public QDialog
{
    Q_OBJECT

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

    EMeasures_t type();

private:
    Ui::CGenericProject *ui;

    virtual void initPlot();

protected:
    QCustomPlot* customPlot;
    QVector<double> m_x;
    QVector<double> m_y;

    EMeasures_t m_type;
};

它有一个名为 initPlotvirtual 方法,它看起来像这样:

void CGenericProject::initPlot()
{
    customPlot = ui->workPlot;

    customPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectAxes );
    customPlot->setFocusPolicy(Qt::ClickFocus);
    customPlot->xAxis->setAutoTickStep(false);
    customPlot->yAxis->setAutoTickStep(false);
    customPlot->xAxis->setTickStep(100);
    customPlot->yAxis->setTickStep(100);
    customPlot->xAxis->setRange(0, 1000);
    customPlot->yAxis->setRange(0, 1000);
}

然后我有一个 class 派生它:

class CEisProject : public CGenericProject
{
public:
    CEisProject();
    ~CEisProject();

private:
    virtual void initPlot();
    void exampleEisMethod();
};

它的 initPlot 在这里:

void CEisProject::initPlot()
{
    // give the axes some labels:
    customPlot->xAxis->setLabel("Re [Ohm]");
    customPlot->yAxis->setLabel("- Im [Ohm]");

    customPlot->replot();
}

这就是我创建 object:

的方式
CGenericProject* test = new CEisProject();

现在,当调用 initPlot() 方法时,首先调用基 class CGenericProject 中的 initPlot(),然后调用 [=23 中的 initPlot() =] 被调用。我想要这个功能,我可以在通用 class 中预定义一些东西,然后在 child 中添加特定的东西。 不过转念一想,initPlot()不应该是排他性的吗?我的意思是,不应该从基础 class child class 调用方法,而不是 both,一个接着一个?我在阅读 this answer.

后注意到了这一点

构造函数:

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

        m_x.clear();
        m_y.clear();
    }

CEisProject::CEisProject()
{
    m_type = EMeasures_t::eEIS;
    initPlot();
}

您没有显示构造函数的定义,只显示了它们的声明。但我很确定构造函数定义包含您问题的答案。

您可能不知道派生 class 构造函数在 将虚函数指向派生 class 之前调用基 class 构造函数 .因此,在基础 class 构造(即将派生的对象 class 中)调用的虚函数获得该虚函数的基础 class 定义。

另外,你的构造函数应该是这样的:

// File .h
CEisProject(QWidget *parent = 0);

// File .cpp
CEisProject::CEisProject(QWidget *parent) : CGenericProject(parent)
{
    ...
}

否则您将无法成为派生小部件的父级。