c – 为什么没有调用copy构造函数?

前端之家收集整理的这篇文章主要介绍了c – 为什么没有调用copy构造函数?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
在这段代码中:
#include <iostream>

using std::cout;

class Foo {
    public:
        Foo(): egg(0) {}
        Foo(const Foo& other): egg(1) {}

        int egg;
};

Foo bar() {
    Foo baz;
    baz.egg = 3;
    return baz;
}

int main(void) {
    Foo spam(bar());
    cout << spam.egg;
    return 0;
}

输出为3,而我预计为1.

这意味着在Foo垃圾邮件(bar())的行中没有调用复制构造函数.

我猜这是因为bar函数不返回引用.

你能解释一下垃圾邮件初始化时真正发生了什么吗?

如果这是一个愚蠢的问题,我提前道歉.

谢谢!

解决方法

复制/移动elision是所谓的“as-if”规则唯一允许的异常,这通常限制了允许编译器对程序执行的变换(例如优化)的种类.

该规则旨在允许编译器执行任何希望的优化,只要转换的程序将工作“好像”是原来的.但是,有一个重要的例外.

根据C11标准第12.8 / 31段:

When certain criteria are met,an implementation is allowed to omit the copy/move construction of a class
object,even if the constructor selected for the copy/move operation and/or the destructor for the object
have side effects
. […] This elision of copy/move operations,called copy elision,is permitted in the following circumstances (which
may be combined to eliminate multiple copies):

  • in a return statement in a function with a class return type,when the expression is the name of a
    non-volatile automatic object (other than a function or catch-clause parameter) with the same cv-unqualified
    type as the function return type,the copy/move operation can be omitted by constructing
    the automatic object directly into the function’s return value

[…]

  • when a temporary class object that has not been bound to a reference (12.2) would be copied/moved
    to a class object with the same cv-unqualified type,the copy/move operation can be omitted by
    constructing the temporary object directly into the target of the omitted copy/move

[…]

换句话说,在12.8 / 31条款适用的情况下,你不应该依赖于被调用或不被调用的构造函数或移动构造函数.

猜你在找的C&C++相关文章