拷贝构造函数(默认的,自定义的,什么时候一定要自定义,什么时候系统会自动调用)

为什么有指针成员的类,要自定义拷贝构造函数

参考了: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,可以完美解决这个问题。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值