c++ new会不会调用构造函数_13图解析C++构造函数和析构函数

67710c90c3582c6b4702d902ccc32e3d.gif

d9d257ab58f51f47d371450c1ec28c04.png

前言

上一章节主要是详细介绍了C++中的类和对象。不清楚的可以回顾一下哦。本章节主要针对于C++构造函数和析构做以详细介绍。

d9d257ab58f51f47d371450c1ec28c04.png

构造函数

构造函数是C++类中的一个特殊的函数,主要有以下特点:

  • 构造函数的名字必须与类名相同

  • 构造函数没有返回值。

  • 构造函数也是特殊的成员函数,

  • 构造函数可以重载

  • 构造函数一般被声明为公有函数

  • 默认构造函数:不写构造函数,存在无参的构造函数

  • 自动调用:构造对象时被调用

  • 调用顺序:创建对象时调用构造函数

故我们可以写出如下代码:

e6f12c7c5743b94ad9f0b9eafe80b534.png

写一个构造函数就是这么简单的哦!

d9d257ab58f51f47d371450c1ec28c04.png谈谈默认构造函数

当我们不写构造函数的时候,为什么可以创建对象,是因为不写构造函数,存在一个无参的构造函数,所以我们可以构造无参对象。其实这个默认的函数我们可以删除掉的,通过C++delete 提供的函数去删除默认的函数,这样的就无法创建对象了。或者你把构造函数私有化也是可以的。

db199efeaa609a95bc15ea9042c24cb8.png

从这一点上来看,可以验证默认的构造函数其实也是无参的。

d9d257ab58f51f47d371450c1ec28c04.png谈谈构造函数与对象的创建

构造函数通常是用来创建对象,也可以理解为对象的属性初始化也可以。并且构造函数决定了对象的长相,构造函数是无参的调用无参构造函数,对象一个参数,构造的对象也就只有一个参数。依次类推要保持一致性。

d725e00f06f4bed7f5ca6ca5d9390777.png

所以一般情况我们为了构建不同的对象,习惯于把构造函数写成缺省的形态,这样就方便了我们构建不同的对象。

谈谈new一个对象的过程

new一个对象其实是两个过程:

  1. new一个无名对象

  2. 把无名对象的首地址给对象指针

所以new一个对象的时候也需要和构造函数的参数一致,如以下代码:

c2e619798a5534e5afd508a5e6d70f29.png

d9d257ab58f51f47d371450c1ec28c04.png

谈谈拷贝构造函数

默认拷贝构造函数

拷贝构造函数也是构造函数,所以也可以用来构造对象的,一般不写拷贝构造函数也是可以使用默认的拷贝构造函数去实现对象的创建,拷贝构造函数只有唯一的一个参数就是对对象的引用,通过拷贝构造函数创建对象的时候需要传入一个参数,如下代码:

11caf53ed8abdf5cb8dc58d77018b303.png

自己也是可以写一个拷贝构造函数,如下代码:

8a283ed90895477751c904fec2ef3264.png

这里this代表的是所有类对象的抽象地址,描述每一个类的想的行为,*this表示对象本身,实现object拷贝到*this。值得一提的是在定义过程当中的赋值运算也是调用拷贝构造函数:

1fe40b1211ac2a887394367e60ebfff2.png

注意普通的赋值运算并不会调用拷贝构造函数如下代码:

6bb0e25e06fd89b5491ccf164e024e34.png

d9d257ab58f51f47d371450c1ec28c04.png

析构函数

析构函数也是C++类中的一个特殊的函数,主要有以下特点:

  • 析构函数的名字必须~类名

  • 析构函数没有返回值。

  • 析构函数没有参数,所以不可重载。

  • 自动调用:析构函数在对象死亡调用

  • 调用顺序:一般情况和创建顺序相反

什么时候需要写析构函数呢?一般当类中的数据成员进行了内存的申请过程,一般都是需要自己手动写析构函数的,如一下代码:

134713145ded462281f8c74ddcccc4b7.png

上述代码主要有三部分组成

  1. 构造函数中:给予属性name申请内存

  2. 主函数中:{}可以提早限制对象的作用域

  3. 析构函数中:释放申请的内存

d9d257ab58f51f47d371450c1ec28c04.png

深拷贝和浅拷贝

为什么有深拷贝和浅拷贝?主要是在使用拷贝构造函数的时候,对一段内存重复释放,导致析构问题,如一下代码:

7852d4cc63e08b5ead3cf1289b995419.png

因为这两个个对象的name属性都是指向同一个内存,所以重复释放内存导致了析构问题。所以才要使用深拷贝去解决这个问题,深拷贝其实很简单,就是在拷贝构造函数中另外申请一段内存,让对象拥有自己的专属内存,实际代码如下:

7d99c4f9fb68da8830a837b902ae998e.png

各自有各自的内存,互不干扰,完美解决问题。

d9d257ab58f51f47d371450c1ec28c04.png

构造顺序和析构顺序

一般情况是构造顺序和析构顺序正好是相反的,如一下代码

01a31666db45ce1c1d5c4587bc02d4b8.png

其实很简单,如果你明白变量的作用域其实就很容易理解调用顺序的。普通对象构造顺序和析构顺序正好是相反的,new出来的对象,释放完后就会调用析构函数,静态对象,程序关闭后调用,所以上图没有显示出来4的析构过程。

d9d257ab58f51f47d371450c1ec28c04.png

对象数组问题

对象数组其实本身就是多个普通的对象,所以当不存在无参的构造函数时候不能构建无参的数组对象,如一下代码:

2303fea1a0090fa5ec349cb7336702d4.png

所以我们要像在C语言中那样创建数组的话, 都会准备一个无参的构造函数,或者是采用缺省的方式编写构造函数。

d9d257ab58f51f47d371450c1ec28c04.png

尾言

关于类的组合问题,我们下个章节探讨,本节课就到这里了,本章节作业: 用C++类的方式实现C语言中的单链表。

上一章节:C++类和对象

7061a44a2c25b95b1f876f430f6ae075.png

C++教程第03课:一文学会创建类和对象

C++教程第02课:一文学会C++string类

C++教程第01课:一文学C++与C的区别(二)

C++教程第01课:一文学C++与C的区别(一)

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值