正在调用派生方法而不是Base
Derived method being called instead of Base
我忘记了当基类方法没有以Derived*
类型的对象的this->
或Derived::
开头时,为什么基类方法会调用派生的虚拟方法。请参阅Arc::SetAngles(…):中的注释行
摘要:
class Shape {
public:
//...
protected:
//...
virtual void CalculateArea()=0;
virtual void CalculateCenter()=0;
private:
//...
};
基础:
void Arc::CalculateArea() {
_area = 0.5 * _radius * _radius * _theta;
}
void Arc::CalculateCenter() {
double e = GetEndAngle();
double s = GetStartAngle();
double d = e - s;
double x = 0.0;
double y = 0.0;
double offset = 0.0;
if(d < 0.0) {
offset = a2de::A2DE_PI;
}
x = (GetPosition().GetX() + std::cos(((s + e) / 2.0) + offset) * _radius);
y = (GetPosition().GetY() + -std::sin(((s + e) / 2.0) + offset) * _radius);
_center = Vector2D(x, y);
return;
}
void Arc::SetAngles(double startAngle, double endAngle) {
if(startAngle < 0.0) {
startAngle += A2DE_2PI;
}
if(endAngle < 0.0) {
endAngle += A2DE_2PI;
}
_startAngle = std::fmod(startAngle, A2DE_2PI);
_endAngle = std::fmod(endAngle, A2DE_2PI);
//must call base version explicitly otherwise Sector:: versions are called when object is of type Sector* regardless if prefaced with this-> or nothing.
Arc::CalculateCenter();
Arc::CalculateLength();
Arc::CalculateArea();
}
衍生:
void Sector::CalculateArea() {
_area = (_radius * _radius * _theta) / 2.0;
}
void Sector::CalculateCenter() {
double x = (4 * _radius) / (3 * a2de::A2DE_PI);
x += this->GetX();
_center = Vector2D(x, GetY());
}
void Sector::SetAngles(double startAngle, double endAngle) {
Arc::SetAngles(startAngle, endAngle);
Sector::CalculateArea();
Sector::CalculateCenter();
}
C++旨在为您提供以下选择:
- 使用非虚拟函数-基类调用使用基类方法
- 使用虚拟函数-基类调用使用派生类方法
你的选择,你想要哪种行为?
也就是说,在你的代码中有一些混乱&继承层次结构。
如果一个扇形IS-a弧,那么可以说(这里的几何参数,而不是OO设计参数)扇形面积和弧面积的计算应该是相同的。看看你们的代码,它们是——你们可能会去掉Sector::CalculateArea
(相同公式的diff代码)。
然而,CalculateCenter
方法对于这两种类型是不同的,并且基类代码不能利用派生类重写(几何参数和OO参数),这强烈表明Sector不是Arc。
您的代码可能是为了继承而继承的,在这种情况下,情况很糟糕。问问自己,正确的继承是否可能同时来自Shape
。
回到一个严格的几何论点,弧不是扇形:弧在圆的周长上(如果你愿意的话,是曲线),扇形是圆的一部分(饼状)。完全不同的实现可以在代码中看到这一点。
相关文章:
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- 通过方法访问结构
- 最小硬币更换问题(自上而下方法)
- C++为构建时间获取QDateTime的可靠方法
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 处理多个异常集合的C++方法
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 有什么方法可以遍历结构吗
- 派生对象调用的 Base 方法的模板推导
- 最有效的安全方法将 std::map<int, std::shared_ptr> 转换为 std::<Base>map<int, std::shared_ptr<D
- 将static_pointer_cast添加到<Derived> std::list<shared_ptr<Base>> 会导致称为 error 的纯虚拟方法
- 如何轻松地将 Base 方法重定向到相同的派生类方法
- Gmock Base类方法中的派生类方法
- 通过"a pointer of the base class"访问未在基类中声明的子类的方法或属性(动态)
- 在不手动键入base::method()的情况下,我可以递归地调用每个基中的方法吗
- 正在调用派生方法而不是Base
- 这是正确的吗:在构造 Base 对象之前调用了派生的虚拟方法
- 有什么方法可以有std::unordered_set<Base>::count(派生的c)?
- 在Python中继承c++的Base,使用SWIG调用抽象方法
- C++:从派生实例调用 base 中的纯虚拟方法重载