下面是一个++操作符重载的例子:
class
Int
... {
public:
Int(int n = 0) : n_(n) ...{}
Int operator ++(int)
...{
Int temp(*this);
n_++;
return temp;
}
Int& operator ++()
...{
n_++;
return *this;
}
private:
int n_;
} ;
... {
public:
Int(int n = 0) : n_(n) ...{}
Int operator ++(int)
...{
Int temp(*this);
n_++;
return temp;
}
Int& operator ++()
...{
n_++;
return *this;
}
private:
int n_;
} ;
初看上面的代码,觉得没有什么问题。但我们运行一下下面的代码:
int
main()
... {
int i = 5, j = 10;
// 此行编译不过,因为i++是一个右值,不可以作为左值来使用
i++ = j++;
++i = ++j;
Int A = 10, B = 20;
// 此行编译通过
A++ = B++;
++A = ++B;
return getchar();
}
... {
int i = 5, j = 10;
// 此行编译不过,因为i++是一个右值,不可以作为左值来使用
i++ = j++;
++i = ++j;
Int A = 10, B = 20;
// 此行编译通过
A++ = B++;
++A = ++B;
return getchar();
}
在i++ = j++;中,我们知道,i++之后返回的是一个临时变量,而内置类型的临时变量是无法做左值的。因此,该行编译出错。但后面的A++ = B++;却能通过编译,这是为什么呢?
原来,A++返回的虽然也是一个临时变量,但该临时变量在该表达式结束之前有效,因此并没有象内置类型那样出现编译错误。
是的,我们应该避免此类问题,我们类的操作符++应该与内置类型的表现一致。我们只需这样修改:
class
Int
... {
public:
Int(int n = 0) : n_(n) ...{}
// add const to avoid things like a++++;
const Int operator ++(int)
...{
Int temp(*this);
n_++;
return temp;
}
Int& operator ++()
...{
n_++;
return *this;
}
private:
int n_;
} ;
... {
public:
Int(int n = 0) : n_(n) ...{}
// add const to avoid things like a++++;
const Int operator ++(int)
...{
Int temp(*this);
n_++;
return temp;
}
Int& operator ++()
...{
n_++;
return *this;
}
private:
int n_;
} ;
返回一个const,就避免了这种不一致。