带和不带默认复制构造函数的 NRVO

NRVO with and without default copy constructor

提问人:f1msch 提问时间:6/8/2022 更新时间:6/8/2022 访问量:90

问:

我制作了一个演示代码,如下所示:

#include <iostream>
using namespace std;
class Test {
public:
    Test();
    ~Test();
    Test(const Test&);
};
Test::Test(const Test& rhs) {
    cout << "do copy constructor function" << endl;
}
Test::Test()
{
    cout << "do constructor function" << endl;
}
Test::~Test() {
    cout << "do deconstructor function" << endl;
}
Test fun1() {
    Test tmp;
    return tmp;    // NRVO
}
int main() {
    Test t1 = fun1();
    return 0;
}

我在 VS2017 发布模式下运行它,c++ 标准设置为 c++17。 结果与预期一样,复制构造函数尚未运行。

但是当我注释掉自定义复制构造函数并再次运行它时:

#include <iostream>
using namespace std;
class Test {
public:
    Test();
    ~Test();
};
Test::Test()
{
    cout << "do constructor function" << endl;
}
Test::~Test() {
    cout << "do deconstructor function" << endl;
}
Test fun1() {
    Test tmp;
    return tmp;    // NRVO
}
int main() {
    Test t1 = fun1();
    return 0;
}

事实证明,NRVO 是无效的,因为构造函数运行一次,而解构函数运行两次。 那么为什么会这样呢?

C++ NRVO

评论

2赞 Scheff's Cat 6/8/2022
作为记录(以及语法检查所抱怨的任何内容):这个东西被称为“析构函数”。;-)
1赞 mch 6/8/2022
它按预期与 gcc 工作:godbolt.org/z/1M75MsscW
1赞 domdrag 6/8/2022
NRVO 不是强制性的,它都是定义的实现。
1赞 Daniel Langr 6/8/2022
使用 MSVC 进行现场演示:godbolt.org/z/GebnYYoTe。当我添加一个非平凡类型的成员变量时,应用了 NRVO:godbolt.org/z/xqc9YM3Wa
0赞 f1msch 6/8/2022
@Scheff'sCat ~~

答: 暂无答案