要了解copy构造函数使用原理,最好是用完整的代码测试一下,看看它是怎么工作,在什么 情况下会被调用,什么 情况下不会被调用,百度了一些名师讲座,在这里讲的也是乱七八糟,与我在实验环境中,实验结果,也不相同。在GCC只有在用一个类对象对另一个同类对象初始化时,才会发生copy构造调用,这包含在函数参数中调用(值传递,实参赋值给形参)。
在VS中的copy构造函数可能会有些不同,没有测试。。
本文例子在MingW GCC 5.2.0 测试通过:
#include <iostream>
using namespace std;
class copyFunc {
public:
copyFunc(int xx = 0, int yy = 0) {
X = xx;
Y = yy;
cout << "LocationA(int,int)有参数构造函数." << this << endl;
;
}
//copy构造函数 完成对象的初始化
copyFunc(const copyFunc & obj) //copy构造函数
{
X = obj.X;
Y = obj.Y;
cout << "copy构造函数. " << this << endl;
}
~copyFunc() {
cout << X << "," << Y << "~LocationA()析构函数." << this << endl;
}
int GetX() {
return X;
}
int GetY() {
return Y;
}
private:
int X, Y;
};
copyFunc g() {
copyFunc A(1, 2);
return A;
}
//1.用一个对像A对去初始化一个对象B,会发生copy构造函数调用
void objplay10(){
copyFunc A(2,4);
copyFunc B = A;
}
//2.用一个对象A对另一个对象赋值,这不会发生copy构造函数调用
void objplay20(){
copyFunc A(2,4);
copyFunc B;
B = A;
}
//3.显式的调用copy构造函数,进行对像初始化
void objplay30(){
copyFunc A(3,4);
copyFunc B(A);
}
//4.在函数中调用一个会创建匿名对象的函数g()
void objplay40() {
g();
}
//5.用匿名对象初始化m 此时c++编译器 直接把匿名对转成m;(扶正) 从匿名转成有名字了m
//这里不会发生调用copy构造函数。
void objplay50() {
copyFunc m = g();
}
//6.将匿名对像赋值给一个对象,此时会相当于创建了两个类对象,这里也不会发生copy函数的调用
void objplay60() {
copyFunc m2(1, 2);
m2 = g();
}
//7. 使用值传递,在函数参数中,相当于将实参初始化给了函数中的形参,所以会发生copy构造函数的调用。
void func70(copyFunc A) {}
void objplay70(){
copyFunc A(4,5);
func70(A);
}
int main() {
//分别测试下面几个函数调用,观察copy构造函数的调用
//objplay10();
//objplay20();
//objplay30();
//objplay40();
//objplay50();
//objplay60();
objplay70();
cout << "end..." << endl;
return 0;
}
深copy和浅copy测试代码,启用不同的copy方法,测试前后变化,如果不定义copy构造函数,默认的情况下,是浅copy。
/*
* 深copy和浅copy.cpp
*
* Created on: 2015年10月25日
* Author: xn666
*/
#include <iostream>
#include <string.h>
#include <stdlib.h>
using namespace std;
class mycopys{
public:
mycopys(){
p = NULL;
len = 0;
cout << "mycopys() call " << this <<endl;
}
mycopys(const char *_p){
len = strlen(_p);
p = (char *)malloc(sizeof(char)*(len+1));
strcpy(p,_p);
cout << "mycopys(*) call " << this <<endl;
}
mycopys(const mycopys & obj){
len = obj.len;
//p = obj.p; //浅copy
p = (char *)malloc(sizeof(char)*(len+1)); //深copy
strcpy(p,obj.p);
//strcpy(p,"dddd");//验证深copy和浅copy是不是同一块内存区
cout << "mycopys(&) call " << this <<endl;
}
~mycopys(){
if(p != NULL){
free(p);
}
len = 0;
cout << "~mycopys() call " << this <<endl;
}
char * get_chars(){
return p;
}
int get_paddress(){
return (int)p;
}
protected:
private:
char *p;
int len;
};
void objplaymain_mycpys(){
mycopys obj1("abcef");
mycopys obj2 = obj1;
printf("obj1:%p,obj2:%p\n",obj1.get_chars(),obj2.get_chars());
printf("%s\n",obj1.get_chars());
printf("%s\n",obj2.get_chars());
}
int main(){
objplaymain_mycpys();
cout << "end" << endl;
return 0;
}