类与对象(3)

发布于:2024-07-19 ⋅ 阅读:(126) ⋅ 点赞:(0)

对于类的构造函数我们已经有了初步的了解,这里我们对其拷贝构造函数进行讲解:

目录

拷贝构造函数:

1.拷贝构造函数的作用:

2.系统生成拷贝构造函数的缺陷

3.深拷贝的实现

侧面体现


拷贝构造函数:


这里我们将拷贝构造函数进行单独来讲,其原因是因为存在深拷贝和浅拷贝问题。这个问题在我初学时也特别困扰我,所以读者开始不会也不要对此想要放弃。接下来我们开始讲解:


1.拷贝构造函数的作用:

用类的对象初始话对象时就要调用拷贝构造函数进行构造

​
class Date
{
	public:
	
		Date(int year=2024,int month=7,int day=10)
		{
          _year=year;
          _month=month;
          _day=day;
		}
		
		~Date()
		{
		 	
		}
	
	private:
		int _year,_month,_day;
		
				
} ;

int main()
{
	Date wang(2024,7,10);
	Date xiao(wang);//这里系统调用默认生成的拷贝构造函数
	return 0;
}

​


2.系统生成拷贝构造函数的缺陷

但是,系统默认生成的拷贝构造函数只是对数据的简单复制,这也就造成了浅拷贝问题:

这里我们可以看到在xiao和wang中指针p指向的空间位置相同,而我们希望的拷贝结果是两者的指针指向不同的空间位置,但是两个空间位置的数据是相同的。同时,在这里当程序运行结束时,析构函数会对该区域进行两次空间释放,从而导致程序运行报错。

这里我们可以将浅拷贝理解为简单的数据复制:

Date(Date&a)
		{
			p=a.p;
			_year=a._year;
			_month=a._month;
			_day=a._day;
		}

3.深拷贝的实现

那么我们如何来解决这一问题来真正意义上实现类的拷贝呢,为此,我们需要自己定义拷贝构造函数,来完成对具有堆区内存开辟的类的拷贝:

class Date {
	public:

		Date(int year=2024,int month=7,int day=10) {
			_year=year;
			_month=month;
			_day=day;
			p=new int[10];
		}

		void Print() {
			cout<<p<<endl;
		}
		void setnumber()
		{
			for(int i=0;i<10;++i)
			{
				*(p+i)=i;
			}
		}
		Date(Date&a)
		{
			p=new int[10];//重新申请内存空间
            //数据拷贝
			for(int i=0;i<10;++i)
			{
				*(p+i)=*((a.p)+i);
			} 
			_year=a._year;
			_month=a._month;
			_day=a._day;
		}

		~Date() {
			delete []p;
		}

	private:
		int _year,_month,_day;
		int*p;

} ;

int main() {
	Date wang(2024,7,10);
	wang.setnumber();
	Date xiao(wang);//类拷贝构造初始化
	wang.Print();//打印地址
	xiao.Print();

	return 0;
}

将两个指针指向的空间位置进行打印:

这样两者指针的指向空间就会不一样,从而避免内存空间的重复释放。

侧面体现

这里也就体现出了一个析构函数的功能,其对于浅拷贝的检查功能。当出现浅拷贝时,由于析构函数会对申请空间进行多次释放,从而导致编译器报错


网站公告

今日签到

点亮在社区的每一天
去签到