来源http://www.learncpp.com/cpp-tutorial/97-overloading-the-increment-and-decrement-operators/
类别声明
class Digit
{
private:
int m_nDigit;
public:
Digit(int nDigit=0)
{
m_nDigit = nDigit;
}
Digit& operator++();
Digit& operator--();
int GetDigit() const { return m_nDigit; }
};
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;
}
我对operator++
的替代实现
Digit& Digit::operator++()
{
return Digit(m_nDigit == 9 ? 0 : (m_nDigit + 1));
}
我想了解
- 如果像我所做的那样创建一个新对象有任何缺点,以及
- 关于如何选择其中一个实现
像您所做的那样创建对象肯定有缺点:
-
它不会编译。不可能将非常量引用绑定到临时引用。
-
即使它进行了编译,也不会执行正确的操作(您的版本使
operator++
将m_nDigit
设置为9
,另一个版本递增m_nDigit
,在达到10
时循环)。 -
即使它确实编译并做了正确的事情,也会非常不安全。返回的引用将绑定到一个临时对象,该对象将在函数返回之前被销毁,这意味着任何访问
operator++
返回值引用的对象的尝试都将导致未定义的行为。
要在这两种实现之间进行选择,您应该选择一种可编译、正确且安全的实现。
三元运算符有问题。此外,您返回的是对象的副本,而不是对象本身,如果您试图重载运算符以像内置类型一样工作,则应始终返回对对象的引用。
我认为你应该这样做:
Digit& Digit::operator++()
{
m_nDigit = (m_nDigit == 9 ? 0 : m_nDigit++);
return *this;
}
或者像这样:
Digit& Digit::operator++()
{
m_nDigit = (++m_nDigit % 10);
return *this;
}
创建一个新对象的缺点是在类似的代码中
Digit d;
++d;
我希望d的值会改变,而对于一个新对象,它不会改变。这个运算符在很多情况下都是这样使用的(不将它分配给变量),所以如果你不增加并返回同一个对象,你就不能这样使用它。
在您的替代实现中,您有两个问题:
-
而不是CCD_ 9做CCD_。当前
m_nDigit
将始终为9,返回值将始终为0。 -
您应该更改
m_nDigit
的值。返回0时,您不会。
return语句有问题,因为运算符应该更改操作数的值,而不是创建新对象。
编辑
要澄清问题,请考虑代码:
Digit x;
x++;
您希望x
作为此代码的结果是什么?我希望是1。使用运算符时,它保持不变。
m_nDigit = 9
是一个赋值,并且将始终被评估为true
- 返回对象的副本,但返回类型是引用。这可能会影响您(请参阅是否可以通过引用返回临时对象)
- 为什么不
m_nDigit = (m_nDigit + 1) % 9;