C++
2023 年 3 月 19 日
[C++] C++编译器 关于构造函数的优化
一些编译器, 针对连续使用的构造函数 会存在一些优化的行为
C++编译器关于构造函数的优化
在本篇文章开始之前,先来思考一道问题:
Widget
是一个类那么,
运行这段代码,拷贝构造函数调用几次?
分析一下:
首先是
f(x)
:
x
传值传参,一次u
拷贝构造v
,一次v
拷贝构造w
,一次w
传值返回,一次一共是
4
次;
然后是
f(f(x))
:
f(x)
的返回值,传值传参,一次u
拷贝构造v
,一次v
拷贝构造w
,一次w
传值返回,一次f(f(x))
的返回值拷贝构造y
,一次一共是
5
次所以综合应该一共是调用
9
次拷贝构造函数
但是,验证一下会发现,结果并不是这样:
为什么呢?
下面来拆分分析一下:
int main() { Widget x; f(x); return 0; }
单独调用:
f(x)
x
传值传参,一次u
拷贝构造v
,一次v
拷贝构造w
,一次w
传值返回,一次所以一共是
4
次拷贝构造:
继续分析之前,先补充一个内容:
匿名对象
什么是匿名对象? 以上面的类为例:
Widget()
就是一个匿名对象的实例化
匿名对象的生命周期,仅在其定义的一行之内
(被取别名当然会延长):如果使用
匿名对象
对 函数f
传参,拷贝构造函数会调用多少次呢?
f(Widget());
分析:
Widget()
传值传参,一次u
拷贝构造v
,一次v
拷贝构造w
,一次w
传值返回,一次所以应该是
4
次但是可以看到,答案是
3
次,这又是为什么呢?原因是:编译器将一个连续的过程——
构造 + 拷贝构造
优化了
f(Widget());
语句中,Widget()
的构造 与 构造完成后的传值传参,就是一个构造 + 拷贝构造
的连续过程 而这个过程会被一些编译器(并不是所有的编译器)
优化为只有、直接构造
而 同样会被优化的 还有
拷贝构造 + 拷贝构造
这个连续过程: 比如:Widget w = f(x);
这个语句按照不优化的分析:
x
传值传参,一次u
拷贝构造v
,一次v
拷贝构造w
,一次w
传值返回,一次f(x)
返回值 拷贝构造w
,一次一共应该是
5
次但是结果是
4
次原因是:
w
传值返回 和f(x)
的返回值 拷贝构造w
,是一个连续的拷贝构造 + 拷贝构造
的过程
会被合并为 一个拷贝构造
如果是
w = f(x)
还有一个赋值的过程,在Widget w = f(x)
中被优化了那么
Widget w = f(f(x));
应该怎么分析呢?
x
传值传参,一次u
拷贝构造v
,一次v
拷贝构造w
,一次w
传值返回,得到f(x)
,一次f(x)
返回值作为参数,传值传参,一次u
拷贝构造v
,一次v
拷贝构造w
,一次w
传值返回,得到f(f(x))
,一次f(f(x))
返回值 拷贝构造w
,一次不优化应该调用
9
次拷贝构造但是,一些编译器对步骤
4、5
,步骤8、9
,会进行优化使其合二为一所以优化过后应该是调用
7
次拷贝构造:
版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)
作者: 哈米d1ch 发表日期:2023 年 3 月 19 日