小谈按值传递时发生拷贝构造
参数传递的方式有三种:按值传递,指针传递(本质其实也是按值传递),引用传递。
其中指针传递和引用传递都可以对实参进行修改,而按值传递不可以,因为按值传递当将实参传递给函数时会发生拷贝操作,产生一个临时对象,而函数实际上是对这个临时对象进行操作。
这里将讲下关于按值传递时发生的拷贝操作以及何时会发生赋值操作:
1 class A 2 { 3 public: 4 A() 5 { 6 printf("CONSTRUCT\n"); 7 } 8 A(const A& a) 9 {printf("COPY CONSTRUCT\n");} 10 void operator=(const A& a) 11 {printf("OPERATOR = \n");} 12 ~A() 13 { 14 printf("DECONSTRUCT\n"); 15 } 16 }; 17 18 A fun(A a){return a;} 19 int main(int argc, char** argv) 20 { 21 A a = A(); //CONSTRUCT 22 23 A d = fun(a); /* 24 COPY CONSTRUCT 25 COPY CONSTRUCT 26 DECONSTRUCT 27 */ 28 29 A b = a; // b - COPY CONSTRUCT 30 A c; // c - CONSTRUCT 31 c = a; // c - OPERATOR= 32 return 0; /* a - DECONSTRUCT 33 c - DECONSTRUCT 34 b - DECONSTRUCT 35 d – DECONSTRUCT */ 36 }
通过这个例子可以看出,在按值传递参数以及按值返回时都会发生拷贝构造。
例子中29行“A b = a; // b - COPY CONSTRUCT”发生的是拷贝构造而不是赋值操作,原因是因为对象b还未初始化。赋值操作只有当对象已经存在的情况下才会发生,就比如31行
“c = a; //c - OPERATOR=”,因为对象c事先已经存在。