相信大家准备找工作的时候,通常都会去刷C++的八股文,通常会看到一道经典的题目,就是深拷贝与浅拷贝。首先,先介绍一下什么叫做拷贝,其实就是复制(因为我入门是学习的C++ Primer Plus这本书),那本书上都是叫做复制构造函数,所以我习惯了,故本文后面都用复制构造函数,只要写过类的都知道,有复制(拷贝)构造函数这个概念,那么我们先举个例子:
从这里可以看出来,这是一个十分基础的例子,有一个构造函数,一个复制构造函数,在主函数s1会先调用默认构造函数,s2再调用复制构造函数。在这里,其实有个非常有意思的问题,你使用Student(const Student& stu)
这句C++语句的时候,你会发现好像复制构造函数一直都是使用的引用,那么是为什么呢?你可以想一下这个过程,结合上面这个例子,如果你不使用引用,Student s2(s1)
首先其会去调用复制构造函数,然后把s1赋值给stu,s1赋值给stu这个过程是不是又在调用复制构造函数呢,那么这个过程是不是卡在这里了?所以对于复制构造函数,必须要使用引用!那么接下来进入正题,深拷贝与浅拷贝,什么叫深?什么叫浅呢?,其实我感觉没有那么高深,要考虑深拷贝的时候,即是类的成员变量中有指针的时候,这个十分关键,如果你成员变量都是普通变量,不涉及到指针,那都是浅拷贝。可能讲的还是不够清晰,我在上面的例子添加几行,举个例子:
此时,我们在增加一个指针变量,char* name
,同样在复制构造函数中,加入复制的过程,运行代码会发现报错。那么是为什么呢?仔细想想代码的运行过程,首先我们创建s1,它会调用默认构造函数,age赋值为10,然后会给name在堆上分配一个空间,其大小为10*sizeof(char),然后创建s2,其的age是等于s1的age,然后同样的,其name也是一个指针,并且同时是指向s1的name那块区域,然后程序结束了,这个时候该调用析构函数了,s1的析构函数将s1的name指向的堆区释放,s2接着调用析构函数,也该释放它的name指向的堆区,但是这个时候该区域已经被s1释放了,这就是问题所在!所以在这种情况的时候,复制构造函数就应该修改!
就添加了name=new char(10)
这一句,那么s2的name它就会指向另外一个区域,此时s1的name和s2的name是指向两个不同的堆内存,但是存放的值是一样的。所以最后总结一句,对于深拷贝还是浅拷贝,其实质是动态内存分配的区域,在C++ primer plus那本书上也叫这个名字!
C++之深拷贝与浅拷贝
于 2023-12-30 17:29:43 首次发布