0

我忘记了为什么基类方法会调用派生的虚拟方法,而该方法的前缀不是this->Derived::类型为对象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();
}
4

1 回答 1

2

C++ 旨在为您提供以下选择:

  1. 使用非虚拟函数 - 基类调用使用基类方法。
  2. 使用虚函数——基类调用使用派生类方法。

你的选择,你想要哪种行为?

也就是说,您的代码和继承层次结构有些混乱。

如果一个 Sector IS-A Arc,那么可以说(这里是几何参数,而不是 OO 设计参数)扇区面积和弧面积的计算应该是相同的。查看您的代码,它们是-您可能会删除Sector::CalculateArea(相同公式的差异代码)。

但是,要求这CalculateCenter两种类型的方法不同,并且基类代码不能利用派生类覆盖(几何参数和 OO 参数),强烈建议扇区不是弧。

您的代码可能是为了继承而继承的,在这种情况下很糟糕。问问自己,正确的继承是否可能来自Shape.

回到严格的几何论点,圆弧不是扇形:圆弧位于圆的周长(曲线,如果您愿意的话),扇形是圆的一部分(饼形)。这可以通过完全不同的实现在您的代码中看到。

于 2012-07-29T08:39:37.570 回答