c++ - 类(class) build 的额外拷贝

标签 c++ constructor copy

在 C++ 中,当初始化类时

MyClass(myBigObject s):
  s_(s)
{
...
}

看起来好像 s 在函数入口处复制了一次(“按值传递”),并在分配给 s_ 时复制了一次。

编译器是否足够聪明,可以删除第一个拷贝?

最佳答案

编译器可以删除第一个拷贝当且仅当

  1. 根据假设规则,拷贝没有可观察到的行为。
    要应用此规则,您的编译器必须知道在编译 MyClass 构造函数的用户时,myBigObject 的构造函数和析构函数都没有任何可观察到的副作用。

    1.9 Program Execution

    The semantic descriptions in this International Standard define a parameterized nondeterministic abstract machine. This International Standard places no requirement on the structure of conforming implementations. In particular, they need not copy or emulate the structure of the abstract machine. Rather, conforming implementations are required to emulate (only) the observable behavior of the abstract machine as explained below.

  2. 或者他们是否可以使用复制省略规则,该规则允许忽略 as-if 规则。
    为此,您必须向构造函数提供一个匿名未绑定(bind)对象。

    12.8 复制和移动类对象§31

    当满足某些条件时,允许实现省略类对象的复制/移动构造,即使对象的复制/移动构造函数和/或析构函数有副作用。在这种情况下,实现将省略的复制/移动操作的源和目标视为引用同一对象的两种不同方式,并且该对象的销毁发生在两个对象本应被删除的时间的较晚时间。 123 这种复制/移动操作的省略(称为复制省略)在以下情况下是允许的(可以组合起来消除多个拷贝):
    — 在具有类返回类型的函数的 return 语句中,当表达式是 a 的名称时 与函数返回类型具有相同 cvunqualified 类型的非 volatile 自动对象(函数或 catch 子句参数除外),可以通过将自动对象直接构造到函数的返回值中来省略复制/移动操作
    — 在 throw 表达式中,当操作数是非 volatile 自动对象(函数或 catch 子句参数除外)的名称时,其作用域不超出最内层的末尾 封闭 try block (如果有),从操作数到异常的复制/移动操作 可以通过将自动对象直接构造到异常对象中来省略对象(15.1)
    - 当未绑定(bind)到引用(12.2)的临时类对象被复制/移动时 对于具有相同 cv-unqualified 类型的类对象,可以通过以下方式省略复制/移动操作 将临时对象直接构造到省略的复制/移动的目标中
    — 当异常处理程序的异常声明(第 15 条)声明与异常对象(15.1)相同类型(cv 限定除外)的对象时,可以通过处理异常声明来省略复制/移动操作作为异常对象的别名,如果除了执行异常声明所声明的对象的构造函数和析构函数之外,程序的含义将保持不变。

通过可移动引用 && 来获取参数要容易得多,它允许在任何情况下用移动替换第二个拷贝。

关于c++ - 类(class) build 的额外拷贝,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24210174/

相关文章:

c++ - 在 debian 中安装 boost(用于 Codeblocks)

c++ - 在 C++ 中初始化结构的语法是什么?

linux - Azure,制作 Linux VM 的副本而不删除原始虚拟机

java - 如何使用 itext7 将页面从一个 PdfDocument 复制到另一个 PdfDocument

php - 使用 PHP 从远程服务器下载多个图像(大量图像)

c++ - 模数代码简化

c++ - 从函数返回 vector 而不破坏它

c++ - 在 for 循环中使用++counter 而不是 counter++

cocoa-touch - 当我们可以写[NSString new]时,为什么我们有[NSString string]?

c++ - 成员初始化列表中的 unique_ptr