在此代码中,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
答案 0 :(得分:3)
您正在体验copy elision和return value optimisation (RVO)。在某些情况下,允许编译器直接在目标空间中构造返回的对象,从而避免创建临时对象并从中进行复制。
这正是您的案例中发生的事情:operator+
的返回值是使用c_object
构造函数直接在(int)
空间构建的,所以你不要&# 39;看到对复制构造函数的调用。
使用GCC,您可以传递命令行标志-fno-elide-constructors
,以防止复制省略。然后,您将看到所有复制构造函数调用。 Live example
答案 1 :(得分:0)
a_object + b_object
是函数调用。返回值是分配给c_object
的值。