浅析C++中的深拷贝与浅拷贝
深拷贝与浅拷贝是C++中的一个常见概念,同时也是各个公司面试中的常考的题目之一。本人曾经有幸被腾讯的面试官问了这一问题,当时回答的感觉不是太好,因此在准备秋招之前再次对该问题进行一次总结,希望能够得到更深的理解。‘
深拷贝与浅拷贝主要是在当类中存在指针的时候会遇到问题,并且深拷贝与浅拷贝的调用情况我个人认为就是是否使用默认的拷贝构造函数的区别。例如我们定义类:
class Student
{
private:
int num;
char *name;
public:
Student();
~Student();
};
其中包含一个char*类型的指针。我们定义构造函数:
Student::Student()
{
name = new char(20);
cout << "Student" << endl;
}
为name指针分配其指向的内存
之后我们定义main函数,并分别定义两个对象,一个对象通过构造函数获得,另一个对象通过默认的拷贝构造函数获得:
int main()
{
{// 花括号让s1和s2变成局部对象,方便测试
Student s1;
Student s2(s1);// 复制对象
}
system("pause");
return 0;
}
我们会发现程序会报错,原因是我们调用了一次构造函数,但是却调用了两次析构函数,导致有一个对象中的char*指针没有成功释放内存,因为它在释放内存的时候其之前指向的内存已经被释放了。
原因就在于,当我们调用默认的拷贝构造函数的时候,我们会发现两个对象中的char*指针其实指向的都是同一块内存,默认拷贝构造函数拷贝了指针,但是没有拷贝指针指向的内存,这就是浅拷贝。
为了防止这种情况的发生,我们需要自己定义拷贝构造函数,函数的参数为该类型的一个对象,在拷贝构造函数中为对象中的指针分配新的内存,这样就能够解决之前的问题,也就是我们平时所说的深拷贝。
Student::Student(const Student &s)
{
name = new char(20);
memcpy(name, s.name, strlen(s.name));
cout << "copy Student" << endl;
}
需要注意的是,拷贝构造函数调用的地方有很多,不仅仅是我们在主动拷贝对象的时候,例如还有在函数的传参过程中,如果我们直接传入对象作为参数而不是对象的引用,则会调用拷贝构造函数,同理函数的对象返回值也会调用拷贝构造函数,这些都是我们在写程序的时候应该注意的地方。
参考博客:https://blog.csdn.net/caoshangpa/article/details/79226270
上一篇: PHP提取中文首字母