我忘了为什么基类方法在方法没有以this->
或类型为Derived::
的{{1}} 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();
}
答案 0 :(得分:2)
C ++旨在为您提供此选择:
您的选择,您想要哪种行为?
这就是说,你的代码中存在一些混乱。继承层次结构。
如果一个扇区IS-A弧,那么可以说(这里的几何参数,而不是OO设计参数)扇区面积和弧面积的计算应该是相同的。看看你的代码,它们是 - 你可能会删除Sector::CalculateArea
(相同公式的差异代码)。
但是,要求CalculateCenter
方法对于这两种类型是不同的,并且基类代码不能利用派生类覆盖(几何参数AND OO参数),强烈建议扇区不是一个弧。
你的代码可能是为了继承而继承,在这种情况下很差。问问自己,正确的继承是否可能来自Shape
。
回到一个严格的几何参数,一个弧不是一个扇区:一个弧在圆的周边(曲线,如果你愿意),一个扇区是圆的一部分(饼形)。这可以通过完全不同的实现在您的代码中看到。