C++多层继承派生类重定义基类同名变量导致计算结果为0问题
问题原因
C++中派生类声明与基类同名的成员变量时,不会覆盖基类成员,只会隐藏基类的同名成员。
你创建的Sphere实例内存中同时存在两个独立的r成员:
- 从
Shape基类逐层继承来的r:这是ThreeDimentional*类型指针直接访问s1->r时操作的成员 Sphere类内部自定义的r:Sphere的area()、volume()方法默认访问的是当前类作用域下的这个成员
你给s1->r赋值为2时,只修改了基类继承来的r,Sphere自身的r始终是未初始化的垃圾值,输出0只是未初始化内存的偶然结果。
修复方案
优先选择第一种方案,从根源上避免同名成员的歧义:
- 删除派生类中重复定义的
r成员,直接复用基类的成员即可。修正后的Sphere类代码如下:
// 提前定义pi常量避免编译错误 constexpr float pi = 3.1415926f; class Sphere : public ThreeDimentional { public: // 删除重复声明的float r; float area() { return 4*pi*pow(r, 2); } float volume() { return float(4)/3*pi*pow(r, 3); } };
修改后你原来的main函数代码不需要任何调整,赋值操作会直接修改唯一的r成员,计算结果正常。
- 如果你有特殊需求必须在派生类保留同名
r成员(不推荐,极易引入隐蔽bug),赋值时需要先将基类指针转换为Sphere*类型,再操作派生类的成员:
int main() { ThreeDimentional* s1 = new Sphere; static_cast<Sphere*>(s1)->r = 2; cout << s1->volume() << endl; }
内容的提问来源于stack exchange,提问作者ParsaAi
相关产品推荐
相关产品推荐

