基类和派生类C ++

时间:2017-03-20 16:17:10

标签: c++ class inheritance

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

     

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

2 个答案:

答案 0 :(得分:5)

第一种情况:

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

第二种情况:

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

参考:Why a virtual call to a pure virtual function from a constructor is UB and a call to a non-pure virtual function is allowed by the Standard?

答案 1 :(得分:2)

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

# fourth pass
# ascending
for i in range(0, len(NA) - 1):
    if isinstance(NA[i], int) and (NA[i] + 1) < len(OA) and NA[i + 1] == OA[NA[i] + 1]:
        NA[i + 1] = NA[i] + 1
        OA[NA[i] + 1] = i + 1

# fifth pass
# descending
for i in range(len(NA) - 1, 0, -1):
    if isinstance(NA[i], int) and (NA[i] - 1) >= 0 and NA[i - 1] == OA[NA[i] - 1]:
        NA[i - 1] = NA[i] - 1
        OA[NA[i] - 1] = i - 1

它与您已有的相同,但有输出。你应该得到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。使用输出,您应该能够重建执行顺序。