通过引用重载运算符传递对象 - C ++

时间:2014-10-08 07:35:55

标签: c++ operator-overloading pass-by-reference

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;
}

4 个答案:

答案 0 :(得分:6)

操作员就像普通的功能一样,仅仅是&#34; fancy&#34;名字:)
(例如operator+()代替sum()

因此,您应用于函数的相同参数传递规则也可以应用于重载运算符。

特别是,当你有一个不便宜的参数要复制时(例如intfloat,是便宜的例子>复制参数; std::vectorstd::string是复制参数便宜的例子),你在中观察这个参数方法(即它是输入只读参数),然后您可以 通过const引用传递 {{ 1}}

通过这种方式,基本上它就像原始参数的地址被传递给函数一样,因此没有涉及深层复制。深拷贝可能非常昂贵,例如想到一个有大量元素的向量。

因此,回顾一下,在以下时间传递 const reference

  1. 参数只是不便宜来复制(例如,对于ints,float等等 不要打扰:按值传递就好了)
  2. 在函数/运算符实现中观察参数 (即它是输入只读参数)

答案 1 :(得分:3)

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

在这种情况下,性能成本可能是微不足道的,并且可以想象编译器可以全部优化它,但它仍然值得做。之后,Keys类可能会变成更复杂的东西。

答案 2 :(得分:0)

考虑一个vector long,其中有1000万个条目。如果您对以下函数进行原型设计:

void foo(vector<long> vl)
{
}

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

有一些类,特别是围绕同步提供程序(关键部分等),以及一些阻止复制构造函数和/或赋值运算符 - 的智能指针类,以便赋值或对象创建不会错误地发生了。虽然可以实现move-constructor或move-assignment-operator。

答案 3 :(得分:0)

通过引用传递的优点:

  1. 它允许我们让函数改变参数的值,这有时是有用的。
  2. 因为没有制作参数的副本,所以它很快,即使与大型结构或类一起使用也是如此。
  3. 我们可以通过const引用来避免无意的更改。
  4. 我们可以从函数返回多个值。
  5. 通过引用传递的缺点:

    1. 因为无法对文字或表达式进行非const引用,所以引用参数必须是普通变量。
    2. 很难判断通过引用传递的参数是输入,输出还是两者都是。
    3. 无法从函数调用中判断出参数可能会发生变化。通过值传递并通过引用传递的参数看起来是相同的。我们只能通过查看函数声明来判断参数是通过值还是引用传递的。这可能导致程序员没有意识到函数会改变参数值的情况。
    4. 因为引用通常由C ++使用指针实现,并且解引用指针比直接访问指针要慢,所以访问通过引用传递的值比访问值传递的值要慢。
    5. 您可以阅读以下内容:

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