例如,在OGRE3D引擎中,我经常会看到像
这样的内容class_name class_name :: operator + (class_name & object)
而不是
class_name class_name :: operator + (class_name object)
嗯,这不是我更喜欢第二种形式,但有没有特别的理由在输入中使用引用?是否有必要使用引用而不是按值复制的特殊情况?或者是表演问题?
答案 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以确保它不被修改以避免副作用。