为什么在运算符重载中需要引用?

时间:2020-02-16 18:19:52

标签: c++ reference operator-overloading pre-increment

在什么情况下重载时需要一个引用,因为没有它,代码仍然可以工作?我知道它与链接有关,但是我不完全理解为什么需要引用。

示例:

Object& operator++();

4 个答案:

答案 0 :(得分:3)

没有“引用”,操作符函数将按值返回 -这将是原始对象的副本-这不是预期的。< / p>

例如,在使用和不使用“引用”的情况下尝试以下代码,您将看到与最终one.show()调用不同的结果:

#include <iostream>

class myInt {
private:
    int value;
public:
    myInt() : value{ 0 } { }
    myInt(int x) : value{ x } { }
//    myInt operator ++() { ++value; return *this; }
    myInt& operator ++() { ++value; return *this; }
    void show() {
        std::cout << value << std::endl;
    }
};

int main(int argc, char* argv[])
{
    myInt one(1);
    one.show();
    myInt two = ++(++one);
    two.show();
    one.show(); // Difference shows here!
    return 0;
}

这是因为在没有引用的情况下,括号外的++one对象的本地创建的副本上运行。

答案 1 :(得分:2)

内置的一元运算符++返回对该运算符所应用的对象的引用。

例如,您可以写

int i = 10;
++++i;

因此,为了模拟相同的行为,用户定义的运算符还应该返回对对象的引用。

答案 2 :(得分:0)

因此,您可以编写类似以下内容的内容:x = i++;我认为不需要它;通常只是以这种方式使用它,并且可能在假定操作员返回值/引用的代码中引起问题-在这种情况下,如果该对象没有返回适当的值,则将无法使用该对象。 。此外,如果操作员做了他们没想到的奇怪事情,其他程序员可能会发现您的代码具有误导性。

注意:某些类型返回对象的副本而不是引用:i++(旧值的副本)与++i(新值)。

答案 3 :(得分:0)

让我们看一下您的示例-我们可能希望将同一对象增加两次,因此,我们可能希望执行以下操作:

#include <iostream>

class MyObject
{
    public:

    MyObject()
    {
        cnt = 0;
    }

    MyObject& operator++()
    {
        ++cnt;
        return *this;
    }

    int cnt;
};

int main()
{
  MyObject obj{};
  std::cout << "The value at start " << obj.cnt << std::endl;
  ++obj;
  std::cout << "The value after increment " << obj.cnt << std::endl;

  ++(++obj); // Legal ONLY when returning a reference!
  std::cout << "The value after two increments in the same time: " << obj.cnt << std::endl;
}

在这种情况下,我们使用链接将计数器增加两次,并且正如我们预期的那样,我们得到以下结果:

The value at start 0
The value after increment 1
The value after two increments in the same time: 3

如果我们应该返回一个对象而不是对 this 的引用,那么我们将对一个l值引用进行操作(因为该对象没有名称!),因此,此链接如以下示例所示,对原始对象将不执行任何操作

#include <iostream>

class MyObject
{
    public:

    MyObject()
    {
        cnt = 0;
    }

    MyObject(const MyObject& other)
    {
        this->cnt = other.cnt;
    }

    MyObject operator++()
    {
        MyObject tmp(*this);

        ++cnt;

        return tmp;
    }

    int cnt;
};

int main()
{
  MyObject obj{};
  std::cout << "The value at start " << obj.cnt << std::endl;
  ++obj;
  std::cout << "The value after increment " << obj.cnt << std::endl;

  ++(++obj); // Legal ONLY when returning a reference!
  std::cout << "The value after two increments in the same time: " << obj.cnt << std::endl;
}

输出:

The value at start 0
The value after increment 1
The value after two increments in the same time: 2