2014-10-08 105 views
2

很新的C++。我看到人们通常在运算符重载中通过引用传递对象。那么,我无法弄清楚什么时候真的有必要。如下面的代码所示,如​​果我在operator +中声明了对象c1和c2时删除了&符号,我仍然会得到相同的结果。在这种情况下,当我们不想修改c1或c2时,是否有任何理由要通过引用?通过引用传递一个对象重载运算符 - C++

#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

如果不通过引用传递对象(或由指针)作为参数,可以通过值将它们传递,这意味着它们被复制;一些对象的复制可能很昂贵。 – piwi 2014-10-08 07:40:04

+0

那么你删除了需要复制的对象作为params的一件事,如果你采取一个参考,所以它可能会更有效率将参数作为参考 – EdChum 2014-10-08 07:40:12

回答

2

运营商们就像普通的功能,只需用“花哨”的名字:)(以下EG operator+()代替sum()

所以,您应用于功能相同的参数传递规则,可以适用于重载运营商也是如此。

特别是,当你有一个参数,该参数是不便宜复制(例如int,一个float,都是廉价复制参数的例子;一个std::vector,一个std::string,都是例子廉价复制参数),和你观察这个参数的方法内(即它是一个输入只读参数),那么你可以传通过const引用(const &)

这样,基本上它就像原始的参数的地址被传递给函数,所以没有深拷贝参与。深拷贝可能非常昂贵,例如想象一个具有大量元素的矢量。

因此,回顾一下,你路过const引用时:

  1. 参数仅仅是不便宜复制(如整型,浮点等只是 不打扰:路过值只是细)
  2. 所述参数是在的功能/操作者执行 观察(即它是一个输入端只读参数)
+0

@ Mr.C64现在在'ostream&operator <<(ostream&out,Something) { \t out << Something << endl; \t退货; }'ostream后的功能是什么? – QuestionMark 2014-10-08 17:55:33

+0

@Farzin:由于'out'是一个_modifiable_参数,所以使用'&',它不是一个只读输入参数。基本上,“out”是对你要附加自己文本的流的引用。这个操作_modifications_流对象,所以你不能通过'const'引用传递它,你必须删除这个const。 – 2014-10-09 09:32:13

+0

@ Mr.C64:我的意思是'&ostream&operator'。 – QuestionMark 2014-10-09 13:46:11

3

如果你通过引用传递,那么没有对象的副本,对于更复杂的类可以大大提高性能。

在这种情况下,性能成本可能是微乎其微的,可以想象编译器可以全面优化它,但仍然值得一试。之后Keys类可能会变成更复杂的东西。

0

考虑一个vectorlong其中有1000万个条目。如果原型的功能,如:

void foo(vector<long> vl) 
{ 
} 

这将导致赋值运算符(或复制构造函数)的vector<long> - 这将需要复制所有这些10米元素。此临时对象的后续析构函数(vl)将取消分配内存并执行其他清理。这肯定会影响性能

有类,特别是周围的同步提供者(临界区等),以及防止拷贝构造和/或赋值操作符的一些智能指针类 - 让转让或对象创建没有按不会发生错误。虽然可以实现移动构造函数或移动赋值运算符。

0

优点通过由参考:

  1. 它使我们能够具有的功能改变参数,有时它是有用的值。
  2. 因为没有创建参数副本,所以即使与大型结构体或类一起使用时也是快速的。
  3. 我们可以通过const引用来避免无意的更改。
  4. 我们可以从一个函数返回多个值。
  5. 传球

缺点通过引用:

  1. 是,由于非const引用不能以文字或表达制成,参考参数必须是正常的变量。
  2. 可能很难判断通过引用传递的参数是输入输出还是两者。
  3. 从函数调用中不可能发现参数可能会改变。通过值传递并通过引用传递的参数看起来是相同的。我们只能通过查看函数声明来判断参数是通过值还是引用传递的。这可能会导致程序员没有意识到函数会改变参数值的情况。
  4. 因为引用通常由C++使用指针来实现,而取消引用指针比直接访问指针要慢,所以访问通过引用传递的值比访问通过值传递的值要慢。

可以读取下面:

http://www.cs.fsu.edu/~myers/c++/notes/references.html