简体   繁体   English

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

[英]Why is a reference needed in operator overloading?

In what situations would a reference be needed when overloading, as the code still works without it?在什么情况下重载时需要引用,因为没有引用代码仍然可以工作? I am aware it has something to with chaining, but I do not understand exactly why the reference is needed.我知道它与链接有关,但我不明白为什么需要引用。

Example:例子:

Object& operator++();

Without the 'reference', the operator function will return by value - and that will be a copy of the original object - which is not what is intended.如果没有“引用”,运算符函数将按返回——这将是原始对象的副本——这不是预期的。

For example, try the following code with and without the use of the 'reference', and you will see different results from the final one.show() call:例如,尝试使用和不使用 'reference' 的以下代码,您将看到与最后的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;
}

This is because, without the reference, the ++ outside the parentheses operates on a locally-created copy of the one object.这是因为在没有引用的情况下,括号外的++one对象的本地创建副本进行操作。

The built-in unary operator ++ returns a reference to the object for which the operator is applied.内置一元运算符 ++ 返回对应用该运算符的对象的引用。

For example you may write例如你可以写

int i = 10;
++++i;

So to simulate the same behavior user-defined operators also should return a reference to object.所以为了模拟相同的行为,用户定义的操作符也应该返回一个对对象的引用。

So you can write something like: x = i++;所以你可以这样写: x = i++; I don't think that it is needed;我认为没有必要; it is just used this way in general and it might cause problem in code that assumes that the operator return the value/reference - in which case you won't be able to utilize your object in that code if it doesn't return appropriate value.它通常只是以这种方式使用,它可能会导致代码出现问题,假设操作符返回值/引用 - 在这种情况下,如果它没有返回适当的值,您将无法在该代码中使用您的对象. Furthermore, other programmers might find your code misleading if operators do weird things they don't expect.此外,如果操作员做了他们意想不到的奇怪事情,其他程序员可能会发现您的代码具有误导性。

Note: some types return copy of the object instead of reference: i++ (copy of old val) vs ++i (new value).注意:某些类型返回对象的副本而不是引用: i++ (旧值的副本)与++i (新值)。

Let's look at your example - we may want to increase the same object twice, therefore, we may wish to do the following:让我们看看您的示例 - 我们可能希望将同一个对象增加两次,因此,我们可能希望执行以下操作:

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

In this case, we increase the the counter twice using chaining, and as we expected, we get the following result:在这种情况下,我们使用链接将计数器增加两次,正如我们预期的那样,我们得到以下结果:

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

If we should return an object and not a reference to this , then, we operate on a l-value reference (since this object doesn't have a name!), therefore, this chaining would do nothing to the original object, as can seen in the following example:如果我们应该返回一个对象而不是对this的引用,那么我们对左值引用进行操作(因为这个对象没有名字!),因此,这个链接不会对原始对象做任何事情,因为可以在以下示例中看到:

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

output:输出:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM