我经常在运算符重载定义中看到什么引用?

时间:2010-10-21 15:28:58

标签: c++ class reference operator-overloading

例如,在OGRE3D引擎中,我经常会看到像

这样的内容
class_name class_name :: operator + (class_name & object)

而不是

class_name class_name :: operator + (class_name object)

嗯,这不是我更喜欢第二种形式,但有没有特别的理由在输入中使用引用?是否有必要使用引用而不是按值复制的特殊情况?或者是表演问题?

5 个答案:

答案 0 :(得分:4)

这是一个性能问题。通过引用传递通常比通过值更便宜(它基本上相当于通过指针传递)。

在不相关的说明中,您可能希望operator+的参数为const class_name &object

答案 1 :(得分:3)

建议在operator+方面实施operator+=。首先复制左参数,然后修改它,最后返回副本。既然你要复制左参数,你也可以通过对左参数使用call by value来做到这一点:

class_name operator+(class_name x, const class_name& y)
{
    return x += y;
}

在C ++ 0x中,您应该为结果启用移动语义:

#include <utility>

class_name operator+(class_name x, const class_name& y)
{
    return std::move(x += y);
}

答案 2 :(得分:2)

除了常规方法的“通常”调用约定之外,我会注意到运算符有点特殊。

使用const&而不是传值的主要原因是正确性(性能排在第二位,至少在我看来)。如果您的值可能是多态的,则复制意味着对象切片,这通常是未定义的行为。

因此,如果你使用pass-by-value,你明确告诉你的调用者该对象将被复制,它不应该是多态的。

另一个原因可能是表现。如果类很小且复制构造函数很小,那么复制它可能比使用间接更快(想想类似int的类)。在其他情况下,传值可以更快,但在非内联情况下,它们更少。

但我确实认为这些都不是真正的原因而且开发人员只是选择了这个......

...因为真正的WTF (正如他们所说)是operator@应该被声明为自由函数,以允许左侧参数的参数提升......

因此,如果他们不遵循这条规则,为什么他们会厌倦通常的论证传递风格?

答案 3 :(得分:1)

这样就不会从原始参数中复制object。事实上,首选方法是将object作为const传递,并将operator+设为const member operator

class_name class_name :: operator + (const class_name& object) const;

答案 4 :(得分:-1)

传递引用比复制类的整个实例要快得多。 此外,如果没有为类定义复制构造函数,复制它可能是危险的(默认复制构造函数将只复制指针,析构函数将删除它们)。

将类传递给方法或运算符时,最好始终传递引用。您可以声明它为const以确保它不被修改以避免副作用。