首页 > 后端开发 > C++ > 正文

为什么在这种情况下我的 C 11 Move 构造函数没有被调用?

Susan Sarandon
发布: 2024-11-05 01:49:02
原创
447 人浏览过

Why Doesn't My C  11 Move Constructor Get Called in This Case?

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

问题

考虑以下类:

<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>
登录后复制

并且它的用法:

<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   <-- why not move?
test
登录后复制

在 VS2010 中,使用默认设置,人们会期望最后一个对象(z)是移动构造的而不是默认的 -建造的。使用 X z( move(X("test")) ) 会产生预期的输出:ctor move test。这可能是 NRVO 的情况吗?

问题

是否应该根据 C 11 标准调用移动构造函数?如果是这样,为什么不调用它?

回答

观察到的行为是由于复制省略造成的。编译器可以直接将临时对象构造到要复制/移动到的目标中,从而省略复制/移动构造函数和析构函数调用。

第 12.8 节中概述了可以应用复制省略的情况。 C 11 标准第 32 条:

  • 在具有类返回类型的函数中,如果返回表达式是与返回类型相同类型的非易失性自动对象。
  • 在 throw 表达式中,如果操作数是非易失性自动对象,其作用域未超出封闭的 try 块。
  • 当复制尚未绑定到引用的类对象时/移动到具有相同类型的类对象。
  • 当异常处理程序通过将异常声明视为别名来声明与异常对象相同类型的对象时。

在这种情况下,编译器能够省略临时 X(“test”)和目标 z 之间的复制或移动操作,从而产生观察到的行为。

以上是为什么在这种情况下我的 C 11 Move 构造函数没有被调用?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!