从++运算符重载来理解++i的效率比i++高的问题
一:
首先弄懂前置++和后置++的概念先。
int m1=10;
int m2=10;
cout<<++m1<<endl; //输出为11,++符号放在变量的前面,这个叫前置++
cout<<m2++<<endl; //输出为10,++符号放在变量的后面,这个叫后置++
二: 现在对运算符++重载
class TestInt
{
public:
TestInt()
{
m_Num=10;
}
//前置++重载,不能返回void类型,因为cout<<++TestInt<<endl这样就编译报错
TestInt & operator++()
{
m_Num++;
return *this;
}
//后置++重载,带上个参数int
TestInt operator++(int)
{
TestInt tmp=*this; //先保存目前的数据
m_Num++;
return tmp;
}
int m_Num;
};
ostream &operator<<(ostream &out,const TestInt &tmp)
{ //重载<<运算符
out<<tmp.m_Num;
return out;
}
int main()
{
TestInt aa;
TestInt bb;
cout<<++aa<<endl;
cout<<bb++<<endl;
return 0
}
运行的结果为:
11
10
由此类我们可以得出结论,TestInt aa; ++aa的效率比aa++高的原因,是因为 aa++是要多分配个内存空间(也就是多了个临时的对象),这样的效率就低了。由此可以推导出++i的效率比i++的高了。
三:
(1)
但是为啥前置++要返回个引用的呢?
TestInt & operator++()
{
m_Num++;
return *this;
}
如果我们返回的不是引用,而只是值,也就是前置++的代码更改成如下:
TestInt operator++()
{
m_Num++;
return *this;
}
这样是不可行的,我们看下前置++返回只是值的话,用main函数里面的代码如下的测试:
int main()
{
TestInt aa;
int tmp=10;
cout<<++(++tmp)<<endl;
cout<<tmp<<endl;
cout<<++(++aa)<<endl;
cout<<aa<<endl;
}
输出的结果为:
12
12
12
11
对上面的输出结果解析:
cout<<++(++tmp)<<endl;
cout<<tmp<<endl;
//++tmp返回的是tmp,返回之后再加tmp进行操作,所以下面单独输出的值是12,tmp的值最终是变成了12
/*======================================================================*/
cout<<++(++aa)<<endl;
这语句里面 ++aa返回只是临时的对象了(因为重载前置++只是返回值),再一次的++操作,也只是对临时的对象操作,所以尽管这里输出的是12
但是cout<<aa<<endl; 这句的输出也只是11,因为最后的操作只是对临时的对象进行操作。
因此前置++的返回必须是引用。
(2)
//后置++
TestInt operator++(int)
{
TestInt tmp=*this; //先保存目前的数据
m_Num++;
return tmp;
}
后置++只能返回值,这是公认的,在书籍或者文档里面一般都这么写的。
但是为啥的呢?
因为这里面返回的是个函数里面的那个临时数据,如果对这个临时数据返回引用的话,第二次再调用这个会出问题的。
同样另话一个原因,编译会报错。