c ++中的基本运算符重载语法

时间:2012-02-06 17:35:35

标签: c++ operator-overloading operator-keyword

我很难形成一个我想问的问题,所以让我举个例子:

假设我们正在开发一个3d系统,我们已经定义了一个矢量类Vec3。我们重载一些算术运算符以获得明显的重复。其中我们重载*运算符,以便它返回两个向量的点积。现在我们的代码应该是这样的:

class Vec3{
private:
    float x, y, z;
public:
    float operator*(const Vec3&) const; //dot product
.
.
.

现在说我们希望能够通过使用带有某些东西的*运算符来缩放我们的向量,比如浮点数。这可以通过声明以下内容来完成:

    Vec3 operator*(const float) const;
    friend Vec3 operator*(const float, const Vec3&);

这有两个超载和我想知道是否有办法只用一个,即我们声明这而不是上面两行:

    friend Vec3 operator*(const Vec3&, const Vec3&);

然后为Vec3 ctor添加默认值以处理来自float的转换。

最后一个例子适用于:

    Vec3 someVec3 = 1.0 * otherVec3; //through friend Vec3 operator*(const float, const Vec3&)

然而不是这样:

    Vec3 someVec3 = otherVec3 * 1.0;

因为编译器不知道要使用哪两个:

    friend Vec3 operator*(const float, const Vec3&); //the one we want to use
or
    float operator*(const Vec3&) const; //the one for the dot product

有什么建议吗?

谢谢!

3 个答案:

答案 0 :(得分:5)

在这种情况下,我最初建议不要对运算符进行重载,因为您的用户如何知道*是否代表点或交叉产品(两者都是合理的含义,具体取决于客户的预期用途)。我实际上建议不要支持operator*并使用dotcrossscale成员进行支持。然后,您不必担心多次重载,并且您的用户可以清楚地知道他们正在获得什么。

但是如果你想继续使用运算符,那么有两个重载是没有错的。创建一个虚拟Vec3进行缩放不仅在语义上不正确,而且会增加少量不必要的开销。

答案 1 :(得分:2)

Boost.Operators可以为您完成大部分的锅炉工作。 E.g:

class Vec3 
  : boost::multipliable2<Vec3, float>
{
public:
   // ... 

   Vec3 operator*=(float);
   // Vec3 operator*(Vec3, const float&) and
   // Vec3 operator*(const float&, Vec3) auto-generated
   // by multipliable. 
};

答案 2 :(得分:1)

在几个重载中没有任何错误,特别是如果它们可以很容易地相互实现的话,那就不会出现错误:

Vec3 operator*(const float scale, const Vec3& vec)
{ return vec * scale; }

很难让它变得简单!