基类和派生类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
.我希望现在你明白为什么你的输出是15
.使用输出,您应该能够重建执行顺序。
相关文章:
- 为什么使用 "this" 指针调用派生成员函数?
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 在派生函数中指定void*参数
- 如何通过派生类函数更改基类中的向量
- 如何委托派生类使用其父构造函数?
- 如何使用单独文件中的派生类访问友元函数对象
- 派生类销毁的最佳实践是什么
- 如何使用基类指针引用派生类成员
- 派生类是否可以在抽象工厂设计模式中具有数据成员
- 使用基类指针创建对象时,缺少派生类析构函数
- 如何引用基类的派生类?
- 存储模板类型以强制转换回派生<T>
- 需要从 istream 和 ostream 派生 iostream
- 在 C++ 中用派生类型重写成员函数
- 具有多个类、派生类的C++正向声明
- 有没有一种"cleaner"的方法可以在指向基的指针向量中找到派生类的第一个实例?
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 如果基类包含双指针成员,则派生类的构造函数
- 为什么此派生对象无法访问基类的后递减方法?
- 有没有比在库中添加一个并非由所有派生类实现的新虚拟函数更好的设计实践