基类和派生类C++

QFi*_*QFi 8 c++ inheritance class

几天前,我想深入了解C++世界.我正在研究基类和派生类的概念.有人可以解释下面两个代码片段的细微差别吗?

class A
{
    private:
    virtual int GetValue() { return 10; }

    public:
    int Calculate() { return GetValue()*1.5; }
};

class B: public A
{
    private:
    virtual int GetValue() { return 20; }
};

int main()
{
    B b;
    std::cout << b.Calculate() << std::endl;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

产量为30,但预计为15

class A
{
    private:
    int m_data;

    public:
    A(): m_data(GetValue()) {}
    int Calculate() { return m_data*1.5; }
    virtual int GetValue() { return 10; }
};

class B: public A
{
    public:
    virtual int GetValue() { return 20; }
};

int main()
{
    B b; A* ap;
    ap=&b; 
    std::cout << ap->Calculate() << std::endl;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

产量为15,但预计为30

有人可以解释并帮助我理解推理吗?我对这个概念的看法出了点问题,但我无法弄明白.

Bat*_*eba 5

第一种情况:

这是微不足道的.您有一个实例化的实例B,并且您计算了在标记为基类时return GetValue() * 1.5;使用的实例.因此评估20*1.5.B::GetValue()GetValue()virtual

第二种情况:

不是那么微不足道.您正在调用GetValue()基本成员初始化程序来为其设置值m_data.标准C++规定GetValue()在这种情况下将调用基类方法.(非正式地认为这是由于在完全构建类之前B没有构建类A).因此评估10*1.5.有趣的是,如果GetValue()纯虚拟的,那么程序的行为将是未定义的.


参考:为什么从构造函数对纯虚函数的虚拟调用是UB,标准允许调用非纯虚函数?