对象拷贝时的编译器优化
- 现代编译器会为了尽可能提高程序的效率,在不影响正确性的情况下会尽可能减少⼀些传参和传返回值的过程中可以省略的拷贝。
- 如何优化C++标准并没有严格规定,各个编译器会根据情况自行处理。当前主流的相对新⼀点的编译器对于连续⼀个表达式步骤中的连续拷贝会进行合并优化,有些更新更"激进"的编译器还会进行跨行跨表达式的合并优化。
构造时的优化
就拿我们之前隐式类型转换举例,原本用一个内置类型来初始化自定义类型,他所进行的操作是先用内置类型来构造一个临时的自定义类型,然后让这个临时的自定义类型进行拷贝构造。
但是在实际运行的时候不是这样的,编译器会直接合二为一,直接将构造与拷贝构造合并成构造。
#include<iostream>
using namespace std;
class A
{
public:
A(int a = 0)
:_a1(a)
{
cout << "A(int a)" << endl;
}
A(const A& aa)
:_a1(aa._a1)
{
cout << "A(const A& aa)" << endl;
}
A& operator=(const A& aa)
{
cout << "A& operator=(const A& aa)" << endl;
if (this != &aa)
{
_a1 = aa._a1;
}
return *this;
}
~A()
{
cout << "~A()" << endl;
}
private:
int _a1 = 1;
};
void f1(A aa)
{}
A f2()
{
A aa;
return aa;
}
但是const引用和上面的不是一回事。
int main()
{
cout << " 隐式类型转换构造:";
//语法上是先构造后拷贝
A aa1 = 1;
cout << endl << "const引用临时变量:";
//这个和上面不是一回事,这就是普通的构造,只不过构造的是临时对象,然后引用这个临时对象
const A& aa2 = 2;
return 0;
}
函数传参的优化
正常我们定义自定义类型,然后传参给函数的行为,编译器是不会优化的,但如果我们匿名对象传参是时候,编译器就会选择优化。
传值返回
返回时⼀个表达式中,连续拷贝构造+拷贝构造->优化⼀个拷贝构造(vs2019 debug版本)
但一些编译器会优化的更厉害,进行跨行优化,直接变成构造(vs2022 debug版本)
我使用的是vs2022
这样也会优化
就相当于用临时对象拷贝构造,编译器就会直接优化成单次构造。
但是在一个表达式中,连续拷贝 + 赋值拷贝 -> 无法优化
结语
这次的分享就到这里结束了~
由于这个内容比较简单,但放在上一篇文章又篇幅过长,所以就单独起一片文章了~
最后感谢您能阅读完此片文章~
如果您认为这篇文章对你有帮助的话,可以用你们的手点一个免费的赞并收藏起来哟~
如果有任何建议或纠正欢迎在评论区留言~
也可以前往我的主页看更多好文哦(点击此处跳转到主页)。