C++拷贝省略和返回值优化

拷贝省略

大多数编译器都会实现拷贝省略来避免多余的数据拷贝。即在特定情况下会省略类的拷贝/移动构造函数,即使有副作用。这种情况下,编译器会把源和省略的拷贝/移动构造函数看作同一object的两种表示方式(实际上应该是两个object),当后续两个object都销毁时,才会调用析构函数。

例如对于以下代码:

struct C {
  C() {}
  C(const C&) { std::cout << "A copy was made.\n"; }
};

C f() {
  return C();
}

int main() {
  std::cout << "Hello World!\n";
  C obj = f();
}

以下输出都是有效的:

Hello World!
A copy was made.
A copy was made.

Hello World!
A copy was made.

Hello World!

完整的拷贝应该是将C()拷贝给f()的临时返回值,在将f()的临时返回值拷贝给obj。
而输出2、3则省略了其中的一种和两种拷贝过程。

返回值优化

返回值优化是拷贝省略的一种实现方式,通常有以下几种方式:

命名的返回值优化

class Thing {
public:
  Thing();
  ~Thing();
  Thing(const Thing&);
};
Thing f() {
  Thing t;
  return t;
}
Thing t2 = f();

返回临时值

class Thing {
public:
  Thing();
  ~Thing();
  Thing(const Thing&);
};
Thing f() {
  return Thing();
}
Thing t2 = f();

临时值作为参数

class Thing {
public:
  Thing();
  ~Thing();
  Thing(const Thing&);
};
void foo(Thing t);

foo(Thing());

抛出异常

struct Thing{
  Thing();
  Thing(const Thing&);
};

void foo() {
  Thing c;
  throw c;
}

int main() {
  try {
    foo();
  }
  catch(Thing c) {  
  }             
}

参考 https://stackoverflow.com/questions/12953127/what-are-copy-elision-and-return-value-optimization/12953145#12953145

猜你喜欢

转载自blog.csdn.net/yjjnls/article/details/83505507