基类和派生类 C++

Posted

技术标签:

【中文标题】基类和派生类 C++【英文标题】:Base and derived classes C++ 【发布时间】:2017-03-20 16:17:09 【问题描述】:

几天前,我想潜入 C++ 世界。我正在研究基类和派生类的概念。有人可以解释以下两个代码 sn-ps 的细微差别吗?

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

有人可以解释并帮助我理解其中的原因吗?我对这个概念的想法有问题,但我无法弄清楚。

【问题讨论】:

解释为什么你认为你的代码会给出这些值。 【参考方案1】:

第一种情况:

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

第二种情况:

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


参考: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?

【讨论】:

您的回复非常有帮助、清晰、完整。在继续课程之前,了解这一点对我来说非常重要。非常感谢。我现在明白了。【参考方案2】:

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

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。我希望现在你明白为什么你的输出是15。通过输出,您应该能够重建执行顺序。

【讨论】:

以上是关于基类和派生类 C++的主要内容,如果未能解决你的问题,请参考以下文章

基类和派生类 C++

C++入门派生类和基类的构造/析构函数关系

C++基类和派生类的构造函数

C++:派生模板类和基类之间的向下转换和向上转换?

C++基类和派生类的构造函数

生成一个派生类对象时,调用基类和派生类构造函数按啥次序