如何控制将返回对象复制到新对象中

How to control the copy of return object into a new object?

本文关键字:对象 复制 新对象 何控制 控制 返回      更新时间:2023-10-16

在这段代码中,operator =被重载以控制类A对象的运算符行为,并且还声明了复制构造函数以查看它是否用于复制过程。

我的问题是,如果输出中没有使用复制构造函数和赋值运算符,编译器会用什么将a_object + b_object的返回对象复制到c_object中?在这种情况下,如何控制复制行为?

#include <iostream>

#define PUTLINE(X)  std::cout<<X<<"----------------------------n" ;
class A{
  int value ;
public:
  A(int v = 0) : value(v) {}
  A(const A & a) 
  { 
    std::cout << "copy constructor...n" ; 
    value = a.value ;
  }
  const A & operator = (const A & a) {
    std::cout << " = operator... n" ;
    this->value = a.value ;    
    return *this ;
  }
  const A operator + (const A & a) {
    return A(value + a.value) ;
  } 
  void print(std::ostream & os) {
    os << value  << std::endl ;
  }
};

int main () {
    A a_object(10); 
    A b_object(20);
    PUTLINE(1);
    A c_object = a_object + b_object ; // what does the compiler use to make this copy? 
    PUTLINE(2);
    A d_object = c_object;
    PUTLINE(3);
    c_object.print(std::cout);
    PUTLINE(4);
    d_object.print(std::cout);
    PUTLINE(5);
    a_object = c_object ;
    PUTLINE(6);
    a_object.print(std::cout);
}

输出如下:

1----------------------------
2----------------------------
copy constructor...
3----------------------------
30
4----------------------------
30
5----------------------------
 = operator... 
6----------------------------
30

您正在经历复制省略和返回值优化(RVO)。在某些情况下,编译器可以直接在目标空间中构造返回的对象,从而避免创建临时对象并从中复制

这正是您的情况:operator+的返回值是使用(int)构造函数直接在c_object的空间中构造的,因此您看不到对复制构造函数的调用。

使用GCC,您可以传递命令行标志-fno-elide-constructors,它可以防止复制省略。然后您将看到所有的复制构造函数调用现场示例

a_object + b_object是一个函数调用。返回值是分配给c_object的值。