基类和派生类 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++的主要内容,如果未能解决你的问题,请参考以下文章