C++ 深复制
接下来,我们准备为大家介绍"深复制"
深复制——当同一个类所定义的不同对象之间进行赋值操作时,且类中定义了复制构造函数,那么,系统就会先调用“复制构造函数”为目标对象重新分配资源的内存空间,例如new操作,打开文件等,然后,再把其它属性一个一个地复制给赋值的目标对象,而这个操作就称为“深复制”。
什么是"复制构造函数"?
其实,就是一个带有参数的构造函数,而这个参数是一个类的对象。
复制构造函数的语法格式如下:
类名(类名 &参数名)
{
代码;
}
语法格式分析:
(1)当前所在类的类名
(2)一对小括号
(3)参数的类形,必须是当前所在类的类名
(4)必须是&
(5)参数名,按C变量命名规则定义即可
(6)一对大括号,大括号中编写主体代码
接下来,我们结合例子作进一步的学习
例子:
class Person //定了一个描述人的类Person
{
public:
char *Name; //名字属性
int age; //年龄属性
Person(char *PN) //带参构造函数
{
Name = new char[50]; //通过new分配一个字符型数组的内存空间,并返回
内存地址给Name
strcpy(Name,PN); //通过srtcpy将参数PN中的名字复制到Name所指向
的空存空间
}
Person( Person &p ) //复制构造函数(参数的类型是Person类)
{
Name = new char[50]; //通过new分配一个字符型数组的内存空间,并
返回内存地址给Name
strcpy(Name,p.Name); //通过strcpy将参数p的属性Name所指向的内存
空间中的名字复制到当前对象的属性Name
所指向的内存空间中
}
}
Person p1; //通过Person类定义了一个对象p1
Person p2 = p1; //通过Person类定义了另一个对象p2,同时,用p1对p2进行赋值
这行代码等价于 Person p2(p1),这样,理解起来就直观一些
注意这行代码在定义p2时,必须立即使用p1对象进行赋值,否则,
不会调用复制构造函数
当把p1赋给p2时,由于,类中定义了“复制构造函数”,
所以,就会先调用复制构造函数,并将p1作为参数,
然后,在复制构造函数中通过new分配内存空间,所以,p2的属性Name与P1的属性Name所指向的内存空间就不一样了。
然后,再通过strcpy复制参数p的属性Name,即复制对象p1的属性Name所指向的内存空间中的内容到p2属性Name所指向的内存空间中。
void main()
{
delete p1.Name; //正确,通过delete释放p1对象中的Name属性所指的内存空间
delete p2.Name; //正确,因为,p2的Name所指向的内存空间在复制构造函数中进行了重新分配
所以,就不会与p1的Name所指向的内存空间一样了
}
小结:
(1)“复制构造函数”只是一个函数,并不会自动分配资源,如果,你需要分配资源,还是要自己动手写代码去分配,如果,没有相应的分配资源代码,如new操作,那么,即使调用了复制构造函数,同样,也是“浅复制”。
(2)当你要进行“深复制”时,也不是一定要实现“复制构造函数”,关键是要理解,资源的分配是指向内存空间,如果,想不同对象分配的资源指向不同的内存空间,就要将new操作再执行一次,而执行的位置也可以在类中的其它方法中进行,不一定要在“复制构造函数”内执行。
通过上面的学习,相信大家对深复制有了一个初步了解,但是,如何灵活地运用这个知识点呢?那么,我们就要通过下方的按钮进入到游戏中,然后,运用该知识点去完成任务,这样,才可以加深大家对该知识点的理解和运用,以及“尽快进入到编程的状态”。
要达到灵活运用,是需要通过不停地反复训练才可以做到,所以,不要停留在理论规则上面,快动起来吧!
(通过游戏模式学习与训练,需要在电脑上运行)