最近研究RB-tree源代码,发现自增和自减的返回类型还不一样:
//前缀
self& operator++(){increment(); return *this;}
//后缀
self operator++(int){
self tmp = *this;
increment();
return tmp;
}
self& operator--(){decrement(); return *this;}
self operator--(int){
self tmp = *this;
decrement();
return tmp;
}
为什么一个有&,一个没有呢?
参照了此博客的讲解:https://www.cnblogs.com/jojodru/archive/2013/01/05/2846476.html
最关键的是左值,右值这个玩意儿,临时对象的开销问题。
#include <iostream>
class UInt{
public:
explicit UInt(int i = 0) : m_int(i) { }
~UInt() { }
UInt(const UInt &rhs) : m_int(rhs.get()) { }
public:
UInt &operator=(const UInt &rhs);
//前缀形式返回一个引用,是一个左值
//后缀形式返回一个const类型,是一个右值,亦即是不能被赋值
UInt &operator++();
const UInt operator++(int);
UInt &operator--();
const UInt operator--(int);
UInt& operator+=(int);
int get(void) const { return m_int; }
void set(int i) { m_int = i; }
private:
int m_int;
};
UInt operator +(const UInt &lhs, const UInt &rhs)
{
UInt result;
result.set(lhs.get() + rhs.get());
return result;
}
UInt& UInt::operator =(const UInt &rhs)
{
m_int = rhs.get();
return *this;
}
//返回一个自身的引用,没有临时对象的代价,性能较高
UInt& UInt::operator ++()
{
*this += 1;
return *this;
}
//返回一个临时对象,增加了一个对象构造和析构的代价,性能较低
//由此可见,对于用户自定义类型,应该尽量使用前缀的increment
const UInt UInt::operator ++(int)
{
UInt oldVal = *this;
++(*this);
return oldVal;
}
UInt& UInt::operator --()
{
*this += (-1);
return *this;
}
const UInt UInt::operator --(int)
{
UInt oldVal = *this;
--(*this);
return oldVal;
}
UInt& UInt::operator +=(int val)
{
m_int += val;
return *this;
}
int main(void)
{
std::cout << "Hello World!" << std::endl;
UInt u1(2);
UInt u2(2);
//Output 2
std::cout << "u1++ return " << (u1++).get() << std::endl;
//Output 3
std::cout << "++u2 return " << (++u2).get() << std::endl;
//Output 3
std::cout << u1.get() << std::endl;
//Output 3
std::cout << u2.get() << std::endl;
return 0;
}
综上,多使用++iterator和–iterator。以及++i,–i。