类与对象(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;
}
将两个指针指向的空间位置进行打印:
这样两者指针的指向空间就会不一样,从而避免内存空间的重复释放。
侧面体现
这里也就体现出了一个析构函数的功能,其对于浅拷贝的检查功能。当出现浅拷贝时,由于析构函数会对申请空间进行多次释放,从而导致编译器报错
原文地址:https://blog.csdn.net/2301_79383371/article/details/140375490
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!