首页 > 后端开发 > C++ > 在 C 中按值返回命名对象时,隐式移动规则如何工作?

在 C 中按值返回命名对象时,隐式移动规则如何工作?

DDD
发布: 2024-11-04 06:20:02
原创
232 人浏览过

How does the Implicit Move Rule work when returning a named object by value in C  ?

按值返回类的命名对象和隐式移动规则

当从函数按值返回类的对象时,隐式移动规则来自进入游戏。此规则控制编译器在构造临时对象来保存返回值时的行为。

示例 1:

考虑以下代码片段:

<code class="cpp">class test {
public:
    test(int y) {
        printf("test(int y)\n");
    }
    test() {
        printf("test()\n");
    }
    test(const test& z) {
        printf("test(const test&z)\n");
    }
    test(test&& s)noexcept {
        printf("test(test&& s)\n");
    }
    test& operator=(test e) {
        printf("test& operator=(test e)\n");
        return *this;
    }
};

test Some_thing() {
    test i;
    return i;
}

int main()
{
    Some_thing();
    return 0;
}</code>
登录后复制

输出:

test()
test(test&& s)
登录后复制

在此示例中,函数 Some_thing 返回使用默认构造函数构造的测试类的命名对象。由于编译器可以通过 NRVO(命名返回值优化)消除副本,因此我们看到默认构造函数 test() 的输出,后跟隐式移动构造函数 test(test&& s)。

示例 2:

现在,让我们修改 Some_thing 函数以使用复制构造函数。

<code class="cpp">class test {
public:
    test(int y) {
        printf("test(int y)\n");
    }
    test() {
        printf("test()\n");
    }
    test(test& z) {
        printf("test(test&z)\n");
    }
    test(test&& s)noexcept {
        printf("test(test&& s)\n");  // Deleted this constructor
    }
    test& operator=(test e) {
        printf("test& operator=(test e)\n");
        return *this;
    }
};

test Some_thing() {
    test i;
    return i;
}

int main()
{
    Some_thing();
    return 0;
}</code>
登录后复制

输出:

test()
test(test&z)
登录后复制

令人惊讶的是,这段代码也可以编译并运行,甚至尽管没有定义移动构造函数。这是因为隐式移动规则会检查表达式 i 是否“适合移动”。在本例中,i 是一个局部变量,可以移动。因此,编译器仍然可以省略复制操作。

隐式移动规则

隐式移动规则在按值返回对象时触发,并且满足以下条件:

  • 表示返回值的表达式是可移动的(即,可以在不违反任何别名规则的情况下将其移动)。
  • 用户定义的复制或移动构造函数/赋值运算符不可行.

结论

隐式移动规则提供了一种高效、简洁的按值返回对象的方法。它有助于优化代码、减少不必要的复制并提高性能。然而,有必要了解它的局限性,并意识到在没有适当考虑的情况下使用它可能会带来的潜在问题。

以上是在 C 中按值返回命名对象时,隐式移动规则如何工作?的详细内容。更多信息请关注PHP中文网其他相关文章!

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