1.值得思考的问题
下面的代码有没有区别?
i++; //i 的值作为返回值,i自增1。
++i; //i自增1,i的值作为返回值
代码示例:
#include <iostream>
using namespace std;
int main()
{
int i = 0;
//++i += 1; //使用这个正常,打印结果2
i++ += 1; //使用这个报错。error: lvalue required as left operand of assignment
cout << "i = " << i << endl;
return 0;
}
编译错误分析:
++i +=1,等效于 ++(i = i + 1),这时候i还是变量,可以进行运算。
i++ +=1,等效于 ++i = 1, 1 = 1 + 1,这时候编译就会犯错误。
2.前置操作符++与后置操作符++的效率
对于基础类型的变量:
-> 前置++的效率与后置++的效率基本相同。
对于类类型的对象:
-> 前置++i的效率高于后置i++。
-> 尽量使用前置++操作符提高程序效率。
代码示例:验证基础类型的变量
#include <iostream>
#include <string>
using namespace std;
int main()
{
int i = 0;
i++;
++i;
return 0;
}
结果:
++i和i++作为单独一行代码时效果一样,查看汇编代码一致。
3.++操作符重载(--操作符自己来)
++操作符可以被重载:
-> 全局函数和成员函数均可进行重载。
-> 重载前置++操作符不需要额外的参数。
-> 重载后置++操作符需要一个int类型的占位参数。
代码示例:验证类类型的对象
#include <iostream>
#include <string>
using namespace std;
class Test
{
int mValue;
public:
Test(int i)
{
mValue = i;
}
int value()
{
return mValue;
}
//返回返回值为引用,表示返回对象本身
Test& operator ++ () //前置++
{
++mValue; //先++
return *this; //再返回
}
//函数返回值为数值(临时对象)
Test operator ++ (int) //后置++,编译器提示,需要占位参数int
{
Test ret(mValue); //保存++之前的mValue值,栈对象ret,多写程序开销
mValue++; //后++
return ret; //先返回,再++
}
};
int main()
{
Test t(0);
t++;
++t;
return 0;
}
分析:
前置++直接在原来的基础上++就好,不需要建立栈对象。
后置++效率低,因为它需要在栈上创建临时对象,出栈时还需要销毁对象;前置++没有这种复杂操作。
小结:
-> 编译优化使得最终的可执行程序更加高效。
-> 前置++操作符和后置++操作符都可以被重载。
-> ++操作符的重载必须符合其原生语义。
-> 对于基础类型,前置++与后置++的效率几乎相同。
-> 对于类类型,前置++的效率高于后置++。