复制方法

dat*_*ili 5 c++ oop

从复制省略方法的标准定义:在C++计算机编程中,复制省略指的是一种编译器优化技术,它消除了不必要的对象复制.让我们考虑以下代码

#include <cstdlib>
#include <iostream>
using namespace std;
int n=0;
struct C 
{
 C (int) {}
 C(const C&) {++n;}      



       };
int main(int argc, char *argv[])
{
    C c1(42);
    C c2=42;




return n;
}
Run Code Online (Sandbox Code Playgroud)

这行"return n"将返回0或1,具体取决于副本是否被删除.

也考虑这段代码

#include <iostream>

struct C {
  C() {}
  C(const C&) { std::cout << "Hello World!\n"; }
};

void f() {
  C c;
  throw c; // copying the named object c into the exception object.
}          // It is unclear whether this copy may be elided.

int main() {
  try {
    f();
  }
  catch(C c) { 
}
}
Run Code Online (Sandbox Code Playgroud)

它说//在异常声明中将异常对象复制到临时对象中.//目前还不清楚是否可以省略此副本.所以我的问题是如果有时候结果是未定义的,那么实现这种优化方法有多大用处?一般来说,它的使用频率是多少?

Dav*_*eas 10

重要的是标准明确允许这一点,这意味着您不能假设复制构造函数的副作用将被执行,因为副本可能被省略.该标准要求复制构造函数的实现具有复制构造函数语义,也就是说,在整个目的中生成在域中与原始对象在语义上等效的第二个对象.如果您的程序符合该程序,则优化不会影响程序.

另一方面,这是我能想到的唯一情况,标准允许来自同一程序的不同可见结果取决于编译器的作用,但是你被告知你不应该有副作用.您的复制构造函数(或者更确切地说,您不能依赖于执行的确切复制数).

至于它是否值得,是的.在许多情况下,副本非常昂贵(我在讨论中故意忽略C++ 11中的move-constructors).考虑一个返回a的函数vector<int>,如果没有删除副本,则需要另一个动态分配,复制所有向量内容然后释放原始内存块,这三个操作都可能很昂贵.

或者,您可以强制用户更改其代码以创建空对象并通过引用传递它,但这将使代码更难以阅读.