今天,继续和大家分享与类和对象相关的知识,本次文章的内容主要分享拷贝构造函数相关的知识。
在学习拷贝构造函数之前,我们先对构造函数和析构函数进行一个总结回顾,在接这往下。
构造函数和析构函数的总结回顾
不论是构造函数还析构函数,我们只需要抓它们的特性,就可以很好的使用它们了。
构造函数
构造函数的特性有七个:
1.函数名与类名相同
2.无返回值
3.构造函数可以重载
4.对象实例化时编译器会自动调用
5.若没有显示写构造函数,编译器会自动生成一个默认构造函数
6.编译器生成的默认构造函数,对于内置类型,有些会进行初始化,有些不会,并没有明确的规定,为此C++11打了个补丁,内置类型在类中的声明时可以给默认值。对于自定义类型会调用它的默认构造函数。
7.不论是无参的构造函数,全给缺省值的构造函数,还是编译器自动生成的默认构造函数,都称之为构造函数。
根据这些特性,可以得出:
1.一般情况下,我们需要写自己写构造函数。
2.在一个类中,内置类型成员给了默认值,自定义类型成员,有自己的默认构造函数了。我们就可以不用写构造函数了。就比如说下面这种情况的类queue
析构函数
析构函数的特性有四个:
1.函数名由波浪号和类名组成
2.析构函数只能有一个,不能重载
3.无返回值
4.若不显示写析构函数,编译器会自动生成一个
对于析构函数,如果没有动态申请空间的资源,可以不用写析构函数,直接使用编译器生成的就行了。像日期类就不用。
还有就是,如果你的成员变量都是自定义类型也不需要写析构函数,因为自定义类型都会调取自己相应的析构函数进行析构。
接下来,我们进入本次的主要内容的讲解。
拷贝构造函数
有时候,我们需要对某些数据进行访问操作,但又需要保护好原数据不丢失。我们通常会进行拷贝一份。C++规定数据的拷贝必须调用相应的拷贝构造函数来进行拷贝。那拷贝构造函数如何定义实现呢?它的定义方式与构造函数有一些类似,也是以类名作为函数名。这里我们以日期类为例,进行演示。
首先,我们以类名作为函数名,然后,完成实现。注意,在定义这个拷贝函数时,不能像43行那样定义传值调用,否则会陷入无限的递归死循环。这是什么原因呢?因为当我们调用拷贝构造函数时,传值给形参d,这里会发生对象的拷贝,而对象的拷贝又会调用拷贝构造函数,就这样一环套一环,一直调用拷贝构造函数,直到栈溢出,程序崩溃。
拷贝构造函数的定义服务器托管网实现我们已经完成了,来看一下效果。
我们先定义一个变量d1,它的日期是2023.9.14,紧接着,我们再以它为拷贝的对象创建对象d2。
从监视窗口,我们可以看到对象d2已经完成了对象d1的拷贝。我们把拷贝函数注释掉看看效果。
从监视窗口中,我们可以发现,即使没有拷贝构造函数,编译器也能完成拷贝的工作,那我们还需要拷贝构造函数做什么呢?
我们以没有写拷贝函数的栈为例:
同样的,我们先定义一个栈s1,然后,以s1为拷贝对象创建对象s2。然后,我们运行一下程序来看看效果。
程序中止了,这是什么原因呢?
这是由于编译器生成的拷贝构造函数,为浅拷贝。从监视窗口看,我们不难发现,对象s1和对象s2的_arr的地址是一样的,也就是它们指向同一块空间
当程序结束时,两个对象都会进行析构,这样一来就对同一个空间析构了两次了。一段空间怎么能析构两次,这显然是荒谬的,于是程序就终止了。
像栈这些自己开辟空间储存数据的结构,我们不能依赖编译器自动生成的拷贝构造函数,我们需要自己写一个拷贝函数,进行深拷贝,为新的对象开辟一段新的空间来存放数服务器托管网据,避免两个对象指向同一段空间的现象出现。
以上是拷贝构造函数的主要用途所在,接下来,我们对它的特征进行总结一下:
1.拷贝构造函数是构造函数的一个重载形式。
2.拷贝构造函数的参数只能有一个且必须是类类型对象的引用,使用传值方式,编译器会报错,因为传值会引发无穷递归。
3.若为显示定义拷贝构造函数,编译器会自动生成一个默认拷贝构造函数。默认拷贝构造函数会根据对象的内存大小完成拷贝,这种拷贝成为浅拷贝。
好了,到这里,我们本次的分享就到此结束了,不知道我有没有说明白,给予你一点点收获。如果你有所收获,别忘了给我点个赞,这是对我最好的回馈,当然你也可以在评论发表一下你的收获和心得,亦或者指出我的不足之处。如果喜欢我的分享,别忘了给我点关注噢。
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.fwqtg.net
发布于我的博客,也许同步更新于博客园 引入 跳表(跳跃表)能够维护一个数的集合(作用类似普通平衡树),查找时间复杂度为 (log n),与平衡树一样基于链表结构。由于不需要平衡树那么多旋转什么的,所以效率比较高,一般认为性能能打红黑树。除此以外,链表的特性使它…