C ++使用两个const参数调用非const运算符重载

时间:2012-08-10 02:17:00

标签: c++ operator-overloading

我为2D矢量(和标量)重载了operator-(和-=):

Vector2D Vector2D::operator-(const Vector2D& rhs) {
    return Vector2D(this->GetX() - rhs.GetX(), this->GetY() - rhs.GetY());
}

为了接到这个电话而不抱怨no operator '-' matches these arguments我必须这样做:

a2de::Vector2D Vector2D::GetFacingVector(const Vector2D& target, const Vector2D& source) {
    a2de::Vector2D facingVec(const_cast<Vector2D&>(target) - const_cast<Vector2D&>(source));
    return facingVec;
}

或者这个:

a2de::Vector2D Vector2D::GetFacingVector(const Vector2D& target, const Vector2D& source) {
    a2de::Vector2D facingVec(Vector2D(target) - Vector2D(source));
    return facingVec;
}

这两件事看起来都很糟糕。 (当你知道自己在做什么时,不要使用“只使用const_cast这句话,因为编译器会假设你这样做!”)

这些是正确的还是有更好的方法来完成同样的事情?

6 个答案:

答案 0 :(得分:2)

您的运营商应该是:

Vector2D Vector2D::operator-(const Vector2D& rhs) const

请注意 const

答案 1 :(得分:2)

您的operator-应声明为const成员函数,这意味着它承诺不会更改*this

Vector2D Vector2D::operator-(const Vector2D& rhs) const {
    return Vector2D(this->GetX() - rhs.GetX(), this->GetY() - rhs.GetY());
}

或者更好的是,让它成为非成员,这样隐式转换可以发生在减号的两侧,而不仅仅是右侧:

inline Vector2D operator-(const Vector2D& lhs, const Vector2D& rhs) {
    Vector2D result(lhs);
    result -= rhs;
    return result;
}

答案 2 :(得分:2)

有很多方法可以使用const。以下是一些可以解决您问题的方法

Vector2D Vector2D::operator-(const Vector2D& rhs) const
{
    return Vector2D(this->GetX() - rhs.GetX(), this->GetY() - rhs.GetY());
}

请注意方法末尾的const?这表示该方法在其范围内保证不会更改任何成员变量

答案 3 :(得分:1)

尝试使用标记运算符作为const成员函数。

答案 4 :(得分:1)

我最好不要写出那些浮现在脑海中的文字。可以这么说,他们会引起这个答案的极端贬低,甚至可能拖累Reddit人群。无论如何,你的成员函数不是const,所以必须在非const参数上调用它。

这是直接的技术修复:

Vector2D Vector2D::operator-(const Vector2D& rhs) const
{
    return Vector2D(this->GetX() - rhs.GetX(), this->GetY() - rhs.GetY());
}

这是一种更好的方式,操作员可以作为一个独立的功能:

Vector2D operator-( Vector2D const& a, Vector2D const& b)
{
    return Vector2D( a.GetX() - b.GetX(), a.GetY() - b.GetY() );
}

最后,考虑一下命名。你有没有写过getSin( angle )?否?

Vector2D operator-( Vector2D const& a, Vector2D const& b)
{
    return Vector2D( a.x() - b.x(), a.y() - b.y() );
}

答案 5 :(得分:0)

另一种可能性是使操作符成为非成员函数。这样您就不会遇到问题。此外,如果你有这样的构造函数,两个参数都可以转换为Vector2D。

class Vector2D
{
...
    Vector2D& operator-=(const Vector2D& rhs)
    {
      this->x -= rhs.GetX();
      this->y -= rhs.GetY();
      return *this;
    }
...
};

Vector2D Vector2D::operator-(const Vector2D& lhs, const Vector2D& rhs)
{
  Vector2D temp(lhs);
  return temp -= rhs;
}

标准中的大多数非修改算术运算符都是非成员对称的。