C ++的新手。我见过人们通常在运算符重载时通过引用传递对象。好吧,我无法弄清楚什么时候真的有必要。如下面的代码所示,如果我在operator +中删除对象c1和c2的声明中的&符号,我仍然会得到相同的结果。当我们不想修改c1或c2时,在这种情况下是否有任何理由通过引用?
#include <iostream>
class Keys
{
private:
int m_nKeys;
public:
Keys(int nKeys) { m_nKeys = nKeys; }
friend Keys operator+(const Keys &c1, const Keys &c2);
int GetKeys() { return m_nKeys; }
};
Keys operator+(const Keys &c1, const Keys &c2)
{
return Keys(c1.m_nKeys + c2.m_nKeys);
}
int main()
{
Keys cKeys1(6);
Keys cKeys2(8);
Keys cKeysSum = cKeys1 + cKeys2;
std::cout << "There are " << cKeysSum.GetKeys() << " Keys." << std::endl;
system("PAUSE");
return 0;
}
答案 0 :(得分:6)
操作员就像普通的功能一样,仅仅是&#34; fancy&#34;名字:)
(例如operator+()
代替sum()
)
因此,您应用于函数的相同参数传递规则也可以应用于重载运算符。
特别是,当你有一个不便宜的参数要复制时(例如int
,float
,是便宜的例子>复制参数; std::vector
,std::string
是复制参数不便宜的例子),你在中观察这个参数方法(即它是输入只读参数),然后您可以 通过const引用传递 {{ 1}} 强>
通过这种方式,基本上它就像原始参数的地址被传递给函数一样,因此没有涉及深层复制。深拷贝可能非常昂贵,例如想到一个有大量元素的向量。
因此,回顾一下,在以下时间传递 const reference :
答案 1 :(得分:3)
如果你通过引用传递,那么就没有对象的副本,对于更复杂的类可以大大提高性能。
在这种情况下,性能成本可能是微不足道的,并且可以想象编译器可以全部优化它,但它仍然值得做。之后,Keys类可能会变成更复杂的东西。
答案 2 :(得分:0)
考虑一个vector
long
,其中有1000万个条目。如果您对以下函数进行原型设计:
void foo(vector<long> vl)
{
}
它将导致vector<long>
的赋值运算符(或复制构造函数) - 并且需要复制所有这些10米元素。稍后此临时对象(vl
)的析构函数将取消分配内存并执行其他清理。它肯定会影响性能
有一些类,特别是围绕同步提供程序(关键部分等),以及一些阻止复制构造函数和/或赋值运算符 - 的智能指针类,以便赋值或对象创建不会错误地发生了。虽然可以实现move-constructor或move-assignment-operator。
答案 3 :(得分:0)
通过引用传递的优点:
通过引用传递的缺点:
您可以阅读以下内容: