1.浅拷贝
如果是一个类,里面没有指针的成员变量,那么深拷贝与浅拷贝没有什么区别,但是有了指针,情况就变了
a.没有指针的类
#include <iostream>
using namespace std;
class Person
{
public:
//char* name;
Person():age(20)
{
//strcpy(name,"zhang");
}
int age;
};
int main()
{
Person p1;
Person p2 = p1;
cout<<p1.age<<endl;
cout<<p2.age<<endl;
cout<<"------------"<<endl;
p1.age =10;
//strcpy(p1.name,"li");
cout<<p1.age<<endl;
cout<<p2.age<<endl;
return 0;
}
输出结果是:
20
20
------------
10
20
可以看出,p1中age修改了,但是没有修改p2中的age,说明,p1和p2中的age指向的地址不一样。
b.有指针的类
#include <iostream>
#include <cstring>
using namespace std;
class Person
{
public:
char* name;
Person():age(20)
{
strcpy(name,"zhang");
}
int age;
};
int main()
{
Person p1;
Person p2 = p1;
p1.age =10;
cout<<p1.age<<" "<<p1.name<<endl;
cout<<p2.age<<" "<<p2.name<<endl;
strcpy(p1.name,"li");
cout<<p1.age<<" "<<p1.name<<endl;
cout<<p2.age<<" "<<p2.name<<endl;
return 0;
}
运行结果是:
10 zhang
20 zhang
10 li
20 li
这里就感觉到了奇怪了,修改了p1的name,为什么p2中的name也一起修改了。那么p2和p1指向的同一个地址,使用p2中的name和p1中的name是一个区域。这是因为,我们没有给Person类写拷贝构造函数,那么我们使用Person p2 = p1;
这条语句的时候,编译器会生成默认的拷贝构造函数,变量name就指向同一个地址。
2.深拷贝
同样以上面类为例子,现在添加一个拷贝构造函数,就可以避免这种问题了。
#include <iostream>
#include <cstring>
using namespace std;
class Person
{
public:
char* name;
Person():age(20)
{
strcpy(name,"zhang");
}
Person(const Person& p)
{
this->age = p.age;
strcpy(name,p.name);
}
int age;
};
int main()
{
Person p1;
Person p2 = p1;
p1.age =10;
cout<<p1.age<<" "<<p1.name<<endl;
cout<<p2.age<<" "<<p2.name<<endl;
strcpy(p1.name,"li");
cout<<p1.age<<" "<<p1.name<<endl;
cout<<p2.age<<" "<<p2.name<<endl;
return 0;
}
运行结果:
10 zhang
20 zhang
10 li
20 zhang
现在我们可以看出,在拷贝构造函数里面,我们手动为每个成员变量赋值,age和name。使用p1和p2中的name成员变量就是指向不同区域,所以修改p1中的name,不会修改p2中的name。
3.总结
如果我们定义的类中有指针,那么我们需要写一个拷贝构造函数,避免出现浅拷贝。