七、C++ 构造函数(中)

文章介绍了C++中默认拷贝构造函数的工作原理及其缺陷,尤其是当对象包含动态分配内存时可能导致的内存问题。随后展示了如何自定义拷贝构造函数以避免这些问题,通过实例演示了如何正确地复制Person类的对象。
摘要由CSDN通过智能技术生成

1.默认的拷贝构造函数

没有构造、析构函数,系统默认为空函数

#include <iostream>
#include <string.h>
#include <unistd.h>

using namespace std;

class Person {
private:
	char *name;
	int age;
	char *work;

public:

	Person() {//cout <<"Pserson()"<<endl;
		name = NULL;
		work = NULL;
	}
	Person(char *name) 
	{
		//cout <<"Pserson(char *)"<<endl;
		this->name = new char[strlen(name) + 1];
		strcpy(this->name, name);
		this->work = NULL;
	}

	Person(char *name, int age, char *work = "none") 
	{
		//cout <<"Pserson(char*, int)"<<endl;
		this->age = age;

		this->name = new char[strlen(name) + 1];
		strcpy(this->name, name);

		this->work = new char[strlen(work) + 1];
		strcpy(this->work, work);
	}

	~Person()
	{
		cout << "~Person()"<<endl;
		if (this->name) {
			cout << "name = "<<name<<endl;
			delete this->name;
		}
		if (this->work) {
			cout << "work = "<<work<<endl;
			delete this->work;
		}
	}

	void setName(char *n)
	{
		name = n;
	}
	int setAge(int a)
	{
		if (a < 0 || a > 150)
		{
			age = 0;
			return -1;
		}
		age = a;
		return 0;
	}
	void printInfo(void)
	{
		//printf("name = %s, age = %d, work = %s\n", name, age, work); 
		cout<<"name = "<<name<<", age = "<<age<<", work = "<<work<<endl;
	}
};

int main(int argc, char **argv)
{
	Person per("zhangsan", 18);
	Person per2(per);  //per2是用per来初始化的,但并没有参数为per的构造函数

	per2.printInfo();

	return 0;
}


执行结果:

name = zhangsan, age = 18, work = none
​~Person()
name = zhangsan
work = none
​~Person()
name = 
work = 

会调用默认的拷贝构造函数,把per的内容拷贝到per2

2.默认的拷贝构造函数的缺陷

它们指向同块内存,会带来什么隐患呢?同一块内存释放两次

释放per时,会把name对应内存释放掉,释放per2时,再次释放name对应内存

所以现在不能使用默认的拷贝构造函数,需要自己实现

3.自己实现拷贝构造函数

#include <iostream>
#include <string.h>
#include <unistd.h>

using namespace std;

class Person {
private:
	char *name;
	int age;
	char *work;

public:

	Person() {//cout <<"Pserson()"<<endl;
		name = NULL;
		work = NULL;
	}
	Person(char *name) 
	{
		//cout <<"Pserson(char *)"<<endl;
		this->name = new char[strlen(name) + 1];
		strcpy(this->name, name);
		this->work = NULL;
	}

	Person(char *name, int age, char *work = "none") 
	{
		//cout <<"Pserson(char*, int)"<<endl;
		this->age = age;

		this->name = new char[strlen(name) + 1];
		strcpy(this->name, name);

		this->work = new char[strlen(work) + 1];
		strcpy(this->work, work);
	}

	Person(Person &per)   //拷贝构造函数
	{
		cout <<"Pserson(Person &)"<<endl;
		this->age = per.age;

		this->name = new char[strlen(per.name) + 1];  //分配新空间
		strcpy(this->name, per.name);                //拷贝值

		this->work = new char[strlen(per.work) + 1];
		strcpy(this->work, per.work);
	}

	~Person()
	{
		cout << "~Person()"<<endl;
		if (this->name) {
			cout << "name = "<<name<<endl;
			delete this->name;
		}
		if (this->work) {
			cout << "work = "<<work<<endl;
			delete this->work;
		}
	}


	void printInfo(void)
	{
		//printf("name = %s, age = %d, work = %s\n", name, age, work); 
		cout<<"name = "<<name<<", age = "<<age<<", work = "<<work<<endl;
	}
};

int main(int argc, char **argv)
{
	Person per("zhangsan", 18);
	Person per2(per);

	per2.printInfo();

	return 0;
}

执行结果:
name = zhangsan, age = 18, work = none
​~Person()
name = zhangsan
work = none
​~Person()
name = zhangsan
work = none

    Person(Person &per)   //拷贝构造函数   引用

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值