自学内容网 自学内容网

类与对象(3)

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

目录

拷贝构造函数:

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;
}

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

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

侧面体现

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


原文地址:https://blog.csdn.net/2301_79383371/article/details/140375490

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!