前置自增(减)和后置自增(减)的区别以 及效率
两者的区别
- 《C专家编程》中说道:“ ++x 表示取 x 的地址,增加它的内容,然后把值放到寄存器中,x++ 则表示取 x 的地址,把他的值装入寄存器中,然后增加内存中的 x 的值”。
- 前置自增(减)返回的是对象的引用,后置自增(减)返回的是对象的拷贝,这就意味着对前置自增(减)的操作会操作对象本身,而后置自增(减)不会。
- 在现代 IDE 中,会优化内置数据类型,统一为前置自增(减),来优化性能,但是对于自定义数据类型的重载,前置自增(减)效率优于后置自增(减)。
为什么前置自增(减)优于后置自增(减)
对于内置数据类型,我们查看反汇编
1
2
3
4
5
6
7
8
9
10
using namespace std;
int main(){
int i = 0;
++i;
i++;
return 0;
}我们发现,运算流程相同,说明编译器对后置自增(减)运算进行了优化
对于自定义数据类型,我们重载自增(减)运算符后查看反汇编
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
using namespace std;
class Test {
public:
Test() :num(0) {};
Test operator++(int) {//后置自增
this->num++;
return *this;
}
Test& operator++() {//前置自增
this->num++;
return *this;
}
int num;
};
int main() {
Test t;
++t;
t++;
return 0;
}或者可以通关禁用拷贝构造函数的方式进行验证
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
using namespace std;
class Test {
public:
Test() :num(0) {};
Test operator++(int) {
this->num++;
return *this;
}
Test& operator++() {
this->num++;
return *this;
}
int num;
private:
Test(const Test& test);//禁用拷贝构造函数
Test& operator=(const Test& test);//禁用赋值运算符
};
int main() {
Test t;
++t;
t++;
return 0;
}会发现后置自增(减)链接错误,说明后置自增(减)调用了拷贝构造函数
总结:不考虑返回值的话,前置自增(减)在编译器不优化的情况下,效率会优 于后置自增(减),因为后置自增(减)会对数据进行一次拷贝,如果数据为自定义数据类型或者为迭代器等,拷贝的代价会非常大,当前置和后置的功能一样时,优先使用前置自增(减)。
评论