为什么有指针成员的类,要自定义拷贝构造函数
参考了:https://blog.csdn.net/caoshangpa/article/details/79226270
没有拷贝构造函数的类,系统会创建默认的拷贝构造函数。(默认拷贝构造函数是浅拷贝,将指针指向旧的对象)
没有拷贝构造函数的对象,拷贝时调用默认拷贝构造函数,
实际为类中的指针成员分配空间一次
(调用默认拷贝构造函数,对象指针指向旧的对象,不为新对象中的指针成员分配空间)。
析构对每个对象,或对象指针执行内存释放,要释放两次,释放新对象的时候没有malloc,直接free(),会发生错误。
调用默认拷贝构造函数例子:
#include <iostream>
using namespace std;
class Student
{
private:
int num;
char *name;
public:
Student();
~Student();
};
Student::Student()
{
name = new char(20);
cout << "Student" << endl;
}
Student::~Student()
{
cout << "~Student " << (int)name << endl;
delete name;
name = NULL;
}
int main()
{
{// 花括号让s1和s2变成局部对象,方便测试
Student s1;
Student s2(s1);// 复制对象 //调用默认拷贝构造函数
}
//执行析构 free(s1.name);成功
// free(s2.name); 没有malloc,直接free(),失败
system("pause");
return 0;
}
调用自定义拷贝构造函数例子:
#include <iostream>
using namespace std;
class Student
{
private:
int num;
char *name;
public:
Student();
~Student();
Student(const Student &s); //拷贝构造函数
};
Student::Student()
{
name = new char[20];
cout << "执行了构造函数" << endl;
}
Student::~Student()
{
delete name;
name = NULL;
cout << "执行了析构函数 " << name << endl;
}
Student::Student(const Student &s) //以student的引用的做入参 const防止s被改变
{
name = new char[20];
memcpy(name, s.name, sizeof(s.name));
cout << "执行了拷贝构造函数" << endl;
}
int main()
{
{ // 花括号让s1和s2变成局部对象,方便测试
Student s1;
Student s2(s1); // 拷贝构造函数
Student s3 = s1; // 拷贝构造函数
}
system("pause");
return 0;
}
总结:
浅拷贝只是对指针的拷贝,拷贝后两个指针指向同一个内存空间。
深拷贝不但对指针进行拷贝,而且对指针指向的内容进行拷贝,经深拷贝后的指针是指向两个不同地址的指针。
系统自动调用拷贝构造函数的地方
1.当函数的参数为对象时,实参传递给形参的实际上是实参的一个拷贝对象,系统自动调用拷贝构造函数实现;
2.当函数的返回值为一个对象时,该对象实际上是函数内对象的一个拷贝(系统自动调用拷贝构造函数实现),用于返回函数调用处。
3:Line line2 = line1;
本质
析构函数释放多次堆内存.
使用std::shared_ptr,可以完美解决这个问题。