首页 > 解决方案 > 这个 C++ 编译器优化的名称是什么(在自身实例上调用对象自己的构造函数),它是如何工作的?

问题描述

我正在尝试学习 C++ 中的资源管理,在我的学习中我遇到了一个有趣的优化。基本上,当使用复制构造函数初始化堆栈上的对象时,其中对象是右值对象(它是右值吗?),而不是调用构造函数然后调用移动构造函数,编译器只是调用原始对象的构造函数。

Object c(Object(1)); // This is the same as Object c(1);
Object c(Object(Object(Object(Object(Object(1)))))); // This is also the same as Object c(1);
Expected flow:
1. Object(1) calls the constructor and creates a nameless Object that will be removed as soon as it's created.
2. c notices this is an rvalue, and calls the move constructor.
3. Destructor for Object(1) is called.
Actual flow:
1. c(1) is called.

这很聪明,但是.. 怎么样?这个技巧背后的机制是什么?即使 Object 的构造函数接受指针和许多参数,这仍然有效。

标签: c++c++11compiler-optimization

解决方案


在 C++17 之前,此行为属于复制省略Object(x)指定创建临时对象,但编译器可以自行决定在某些情况下省略创建和销毁所有临时对象。

由于 C++17发生了这种变化,现在Object(x)意味着迟早会Object使用初始化程序创建一个x。该对象称为结果对象,结果对象的标识由该表达式出现的上下文确定,在您的代码c中是该形式的所有表达式的结果对象,并且两行与Object c(1);. 这适用于类别prvalue的所有表达式。

后者为编码人员提供了更多的确定性,即不会制作不必要的副本。


推荐阅读