前言
上一章节主要是详细介绍了C++中的类和对象。不清楚的可以回顾一下哦。本章节主要针对于C++构造函数和析构做以详细介绍。
构造函数
构造函数是C++类中的一个特殊的函数,主要有以下特点:
构造函数的名字必须与类名相同。
构造函数没有返回值。
构造函数也是特殊的成员函数,
构造函数可以重载
构造函数一般被声明为公有函数
默认构造函数:不写构造函数,存在无参的构造函数
自动调用:构造对象时被调用
调用顺序:创建对象时调用构造函数
故我们可以写出如下代码:
写一个构造函数就是这么简单的哦!
谈谈默认构造函数当我们不写构造函数的时候,为什么可以创建对象,是因为不写构造函数,存在一个无参的构造函数,所以我们可以构造无参对象。其实这个默认的函数我们可以删除掉的,通过C++delete 提供的函数去删除默认的函数,这样的就无法创建对象了。或者你把构造函数私有化也是可以的。
从这一点上来看,可以验证默认的构造函数其实也是无参的。
谈谈构造函数与对象的创建构造函数通常是用来创建对象,也可以理解为对象的属性初始化也可以。并且构造函数决定了对象的长相,构造函数是无参的调用无参构造函数,对象一个参数,构造的对象也就只有一个参数。依次类推要保持一致性。
所以一般情况我们为了构建不同的对象,习惯于把构造函数写成缺省的形态,这样就方便了我们构建不同的对象。
谈谈new一个对象的过程new一个对象其实是两个过程:
new一个无名对象
把无名对象的首地址给对象指针
所以new一个对象的时候也需要和构造函数的参数一致,如以下代码:
谈谈拷贝构造函数
默认拷贝构造函数
拷贝构造函数也是构造函数,所以也可以用来构造对象的,一般不写拷贝构造函数也是可以使用默认的拷贝构造函数去实现对象的创建,拷贝构造函数只有唯一的一个参数就是对对象的引用,通过拷贝构造函数创建对象的时候需要传入一个参数,如下代码:
自己也是可以写一个拷贝构造函数,如下代码:
这里this代表的是所有类对象的抽象地址,描述每一个类的想的行为,*this表示对象本身,实现object拷贝到*this。值得一提的是在定义过程当中的赋值运算也是调用拷贝构造函数:
注意普通的赋值运算并不会调用拷贝构造函数如下代码:
析构函数
析构函数也是C++类中的一个特殊的函数,主要有以下特点:
析构函数的名字必须~类名。
析构函数没有返回值。
析构函数没有参数,所以不可重载。
自动调用:析构函数在对象死亡调用
调用顺序:一般情况和创建顺序相反
什么时候需要写析构函数呢?一般当类中的数据成员进行了内存的申请过程,一般都是需要自己手动写析构函数的,如一下代码:
上述代码主要有三部分组成
构造函数中:给予属性name申请内存
主函数中:{}可以提早限制对象的作用域
析构函数中:释放申请的内存
深拷贝和浅拷贝
为什么有深拷贝和浅拷贝?主要是在使用拷贝构造函数的时候,对一段内存重复释放,导致析构问题,如一下代码:
因为这两个个对象的name属性都是指向同一个内存,所以重复释放内存导致了析构问题。所以才要使用深拷贝去解决这个问题,深拷贝其实很简单,就是在拷贝构造函数中另外申请一段内存,让对象拥有自己的专属内存,实际代码如下:
各自有各自的内存,互不干扰,完美解决问题。
构造顺序和析构顺序
一般情况是构造顺序和析构顺序正好是相反的,如一下代码
其实很简单,如果你明白变量的作用域其实就很容易理解调用顺序的。普通对象构造顺序和析构顺序正好是相反的,new出来的对象,释放完后就会调用析构函数,静态对象,程序关闭后调用,所以上图没有显示出来4的析构过程。
对象数组问题
对象数组其实本身就是多个普通的对象,所以当不存在无参的构造函数时候不能构建无参的数组对象,如一下代码:
所以我们要像在C语言中那样创建数组的话, 都会准备一个无参的构造函数,或者是采用缺省的方式编写构造函数。
尾言
关于类的组合问题,我们下个章节探讨,本节课就到这里了,本章节作业: 用C++类的方式实现C语言中的单链表。
上一章节:C++类和对象
C++教程第03课:一文学会创建类和对象
C++教程第02课:一文学会C++string类
C++教程第01课:一文学C++与C的区别(二)
C++教程第01课:一文学C++与C的区别(一)