繁体   English   中英

基类和派生类C ++

[英]Base and derived classes C++

几天前,我想深入了解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;
}

产量为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;
}

产量为15,但预计为30

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

第一种情况:

这是微不足道的。 你有一个实例化的B实例,你计算return GetValue() * 1.5; 它使用B::GetValue()因为您已将GetValue()标记为基类中的virtual 因此评估20 * 1.5。

第二种情况:

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


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

对第二个示例尝试以下代码:

class A
{
private:
int m_data;

public:
A(): m_data(GetValue()) { std::cout << "Init m_data and A ";}
int Calculate() { return m_data*1.5; }
virtual int GetValue() { std::cout << "GetValue from A ";return 10; }
};

class B: public A
{
public:
B() { std::cout << "Init B "; }
virtual int GetValue() { std::cout << "GetValue from B"; return 20; }
};

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

return 0;
}

它与您已有的相同,但有输出。 你应该GetValue from A Init m_data and A Init B 15获得GetValue from A Init m_data and A Init B 15 我希望你现在明白你为什么输出15 使用输出,您应该能够重建执行顺序。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM