简体   繁体   English

实现前缀运算符++

[英]implementing prefix operator++

From http://www.learncpp.com/cpp-tutorial/97-overloading-the-increment-and-decrement-operators/ http://www.learncpp.com/cpp-tutorial/97-overloading-the-increment-and-decrement-operators/

Class declaration 类声明

class Digit
{
private:
    int m_nDigit;
public:
    Digit(int nDigit=0)
    {
        m_nDigit = nDigit;
    }

    Digit& operator++();
    Digit& operator--();

    int GetDigit() const { return m_nDigit; }
};

Their implementation of operator++ 他们对operator++实现

Digit& Digit::operator++()
{
    // If our number is already at 9, wrap around to 0
    if (m_nDigit == 9)
        m_nDigit = 0;
    // otherwise just increment to next number
    else
        ++m_nDigit;

    return *this;
}

My alternate implementation of operator++ 我的operator++替代实现

Digit& Digit::operator++()
{
    return Digit(m_nDigit == 9 ? 0 : (m_nDigit + 1));
}

I wanted to know 我想知道

  1. if there are any downsides of creating a new object like I have done, and 如果像我一样有创建新对象的缺点,并且
  2. about how to choose one of these implementations? 关于如何选择这些实现之一?

There certainly are downsides to creating an object as you have done: 当然,创建对象有一些缺点:

  1. It will not compile. 它不会编译。 It is impossible to bind a non-const reference to a temporary. 将非常量引用绑定到临时对象是不可能的。

  2. Even if it did compile it would not perform the correct operation (your version makes operator++ set m_nDigit to 9 , the other version increments m_nDigit , wrapping around when 10 is reached). 即使它编译它不会执行正确的操作(你的版本,使operator++设置m_nDigit9 ,其他的版本递增m_nDigit ,当周围包裹10到达)。

  3. Even if it did compile and do the right thing, it would be very unsafe. 即使它确实编译并做了正确的事情,也将是非常不安全的。 The returned reference would be bound to a temporary object which would be destroyed before the function returned, this would mean that any attempt to access the object referenced by the return value of operator++ would result in undefined behaviour. 返回的引用将绑定到一个临时对象,该对象将在函数返回之前被销毁,这意味着任何尝试访问operator++返回值所引用的对象都将导致未定义的行为。

To choose between the two implementations, you should pick the one which compiles, is correct and is safe. 要在这两种实现之间进行选择,您应该选择一种可以编译,正确且安全的实现。

You have a problem with the ternary operator. 您对三元运算符有疑问。 Also you are returning a copy of the object not the object itself, and if you are trying to overload the operator to work like a built-in type, you should always return a reference to the object. 另外,您将返回对象的副本,而不是对象本身,并且,如果您试图使运算符重载以像内置类型一样工作,则应始终返回对该对象的引用。

I think you should do it like this: 我认为您应该这样做:

Digit& Digit::operator++()
{
    m_nDigit = (m_nDigit == 9 ? 0 : m_nDigit++);
    return *this;
}

Or like this: 或像这样:

Digit& Digit::operator++()
{
    m_nDigit = (++m_nDigit % 10);
    return *this;
}

The downside of creating a new object is that in code like: 创建新对象的不利之处在于代码:

Digit d;
++d;

I would expect the value of d to change and with a new object it doesn't. 我希望d的值能够更改,而对于新对象则不会。 This operator is in many cases used like this (without assigning it to a variable) so if you don't increase and return the same object, you can't use it like that. 在很多情况下都使用此运算符(不将其分配给变量),因此,如果不增加并返回相同的对象,就不能那样使用它。

In your alternative implementation you have 2 issues: 在您的替代实现中,您有2个问题:

  1. instead of m_nDigit = 9 do m_nDigit == 9 . 代替m_nDigit = 9m_nDigit == 9 Currently m_nDigit will always be 9, and the return value will always be 0. 当前, m_nDigit始终为9,返回值始终为0。

  2. you're supposed to change the value of m_nDigit . 您应该更改m_nDigit的值。 When returning 0 - you don't. 返回0时-您不这样做。

The return statement is problematic because the operator is expected to change the value of the operand, not to create a new object. return语句有问题,因为期望运算符更改操作数的值,而不是创建新的对象。

edit 编辑

To clarify the problem, consider code: 为了澄清问题,请考虑以下代码:

Digit x;
x++;

What would you expect x to be as the result of this code? 您希望x作为此代码的结果是什么? I would expect it to be 1. Using your operator, it remains unchanged. 我希望它是1。使用您的运算符,它将保持不变。

  1. m_nDigit = 9 is an assignment and will always be evaluated to true . m_nDigit = 9是一个赋值,它将始终被评估为true
  2. You return a copy of the object but return type is a reference. 您返回对象的副本,但返回类型是引用。 This may bite you (see Is returning a temp-object by reference possible ). 这可能会咬你(请参阅可以通过引用返回临时对象 )。
  3. Why not m_nDigit = (m_nDigit + 1) % 9; 为什么不m_nDigit = (m_nDigit + 1) % 9; ?

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

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