问题:
下面的代码有没有区别?为什么?
i++; // i 的值作为返回值, i 自增1
++i; // i 自增1, i 的值作为返回值
在VS2013分析:
i++;
00950D45 mov eax,dword ptr [i]
00950D48 add eax,1
00950D4B mov dword ptr [i],eax
++i;
00950D4E mov eax,dword ptr [i]
00950D51 add eax,1
00950D54 mov dword ptr [i],eax
两种形式在汇编层面是没有区别,在没有返回值的情况下编译器会优化,即两个的值是一样的,++i和i++ 作为单独的代码出现在工程里面本质是没有区别的。
- 现代编译器产品会对代码进行优化
- 优化会使得最终的二进制程序更加高效
- 优化后的二进制程序丢失了C/C++的原生语义
- 不可能从编译后的二进制程序还原C/C++程序
问题:
++ 操作符可以重载嘛?如何区分前置 ++ 和 后置 ++ ?
++ 操作符可以被重载
- 全局函数和成员函数均可以进行重载
- 重载前置 ++ 操作符不需要额外的参数
- 重载后置 ++ 操作符需要一个 int 类型的占位参数
class Test
{
int m_value;
public:
Test(int i)
{
m_value = i;
}
int value()
{
return m_value;
}
Test& operator ++()
{
++ m_value;
return *this;
}
// 后置++不用引用返回的原因
Test operator ++ (int)
{
Test ret(m_value);
m_value ++;
return ret;
}
};
int main()
{
Test t1(0);
Test t2(0);
t1 = ++ t1;
t2 = t2 ++;
cout << t1.value() << endl; // 1
cout << t2.value() << endl; // 0
return 0;
}
分析:
++t1 不需要额外的内存,所以效率更高(不需要在堆上分配空间,也不需要调用构造函数和析构函数)
面试的试题:
对于这两种的真正的区别?
对于基础类型的变量
- 前置 ++ 的效率与后置 ++ 的效率基本相同
- 根据项目组编码规范进行选择
对于类类型的对象
- 前置 ++ 的效率高于后置 ++
- 尽量使用前置 ++ 操作符提高程序效率
小结
- 编译优化使得最终的可执行程序更加高效
- 前置 ++ 操作符和后置 ++ 操作符都可以被重载
- ++ 操作符的重载必需符号其原生语义
- 对于基础类型,前置 ++ 与后置 ++ 的效率几乎相同
- 对于类类型,前置 ++ 的效率高于后置 ++