首页 > 后端开发 > C++ > 为什么启用复制消除后,C 11 中未调用移动构造函数?

为什么启用复制消除后,C 11 中未调用移动构造函数?

DDD
发布: 2024-11-06 09:46:02
原创
301 人浏览过

Why Is the Move Constructor Not Called in C  11 When Copy Elision Is Enabled?

C 11 未调用移动构造函数,首选默认构造函数

使用 C 中的类时,预计将使用移动构造函数高效的资源转移。但是,在某些情况下,可能会意外选择默认构造函数。

问题陈述

考虑以下类:

<code class="cpp">class X {
public:
    explicit X(char* c) { cout << "ctor" << endl; init(c); }
    X(X& lv)  { cout << "copy" << endl;  init(lv.c_); }
    X(X&& rv) { cout << "move" << endl;  c_ = rv.c_; rv.c_ = nullptr; }

    const char* c() { return c_; }

private:
    void init(char* c) { c_ = new char[strlen(c) + 1]; strcpy(c_, c); }
    char* c_;
};</code>
登录后复制

With示例用法:

<code class="cpp">X x("test");
cout << x.c() << endl;
X y(x);
cout << y.c() << endl;
X z(X("test"));
cout << z.c() << endl;</code>
登录后复制

预期输出为:

ctor
test
copy
test
ctor move test
登录后复制

但是,最后一行意外输出“ctor”而不是“move”。

说明

根据 C 11 标准,在某些情况下应该调用移动构造函数。在这种情况下,当用 X("test") 构造 z 时应该发生移动。但是,会调用默认构造函数。

此行为是由于复制省略造成的,这是一种优化技术,允许编译器直接将临时对象构造到目标中,而无需执行复制或移动操作。此优化适用于编译器确定复制/移动操作是不必要的并且可以省略的情况。

在给定场景中,编译器认为临时 X("test") 是复制省略的候选者,因为它是在同一个表达式中自动创建和销毁的。因此,它省略了移动操作并直接使用临时数据构造 z,从而导致调用默认构造函数。

结论

复制省略可能会导致意外的结果使用移动构造函数时的行为,因为它可以防止在预期的情况下调用移动构造函数。编译器可以根据其优化启发式应用复制省略,这可能因编译器和优化设置而异。了解复制省略及其对程序行为的潜在影响非常重要。

以上是为什么启用复制消除后,C 11 中未调用移动构造函数?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板