C++类和对象

1.类的6个默认成员函数

按照定义来说是假如你写了一个空的类,但是他真的是一个空类嘛,或许不是,编译器会自动帮你生成6个成员函数,那这六个成员函数是什么呢,又有哪些作用呢?

接下来我们一起来讨论他们的作用吧。

构造函数

我们看这张图,我们原来在创建某一个对象的时候,先要创建一个对象,然后再给他初始化,那么今天的构造函数就能帮我们在创建的时候完成初始化。

首先强调构造函数的形式,函数没有返回值,名字与类名相同,对象实例化时自动调用构造函数,构造函数可以重载

首先说下格式

构造函数还是能够带参数的(还可以给上一个缺省值),比如说

那上面说的对象实例化是啥意思呢?按照我自己的理解就是你创建了一个对象,然后给对象中的一些变量赋值,就想我们创建对象d的时候,你通过调试就可以看到他会直接进入构造函数。

那构造函数的重载又是怎样一回事呢?

大家看这个代码能通过编译嘛?答案是不能,因为我们在创建对象d的时候会出现两个默认的构造函数,因为第二个构造函数是全缺省函数,所以也能进入,那么编译器就不知道要进入哪一个构造函数,因此报错。

但是我们修改一下,就可以构成函数重载

另外想跟大家说的一点就是,这个构造函数不是默认生成的嘛,为什么还要我们去写呢?我想跟大家说的是,如果你的类里都是内置类型(包括int和char等等还有所有的指针都是内置类型),在你没写构造函数的情况下,那么编译器就会调默认的构造函数,但是这个默认的构造函数也不会帮你初始化。

这是编译器生成的默认构造函数调用的结果,依旧是随机值,那么这个编译器生成的构造函数又有什么用呢?我们会发现,编译器默认生成的构造函数会对自定义类型成员调用它的默认成员函数,我就跟大家详细说一下。

上方我创建了两个类,在其中的Data类中我创建了一个Time类的对象,那么我现在创建一个Data类的对象,在调用编译器默认的构造函数的时候,会碰到自定义类型Time,那么就会自动调用Time类中的默认构造函数,所以默认构造函数就有这样一个作用(小编提醒大家对于自定义类型的对象,编译器是没有默认生成的构造函数的,往往需要我们自己去写)

注意:在C++11中针对内置类型成员不初始化的缺陷,又打了补丁,即:内置类型成员在类中声明可以给默认值。

就是说在C++11中可以在变量声明处给默认值,然后我们创建对象时就调用的编译器默认生成的构造函数就能够自动初始化了。

析构函数

析构函数主要在对象销毁前完成资源的清理,具体是如何清理的呢,我们接着往下。

首先要了解析构函数的特征:

1.析构函数名是在类名前面加~

2.无参数无返回值类型

3.不能构成函数重载

4.在对象声明周期结束时,系统自动调用析构函数

上面是我们自己写的一个析构函数,即使我们不写编译器也会自动生成析构函数,编译器默认生成的析构函数可以起到一个调用自定义类型的构造函数的作用

当程序结束的时候就会调用Stack类的析构函数,但是由于Stack中含有Time类型的对象,属于自定义类型,所以就会要调用Time的析构函数

拷贝构造函数

拷贝构造函数:只要单个形参,该形参是对类类型对象的引用(一般用const修饰),在用已存在的类类型对象创建新对象时由编译器自动调用。

拷贝构造函数的特征:

1.拷贝构造函数是构造函数的重载形式(意味着要有拷贝构造函数,必须先要写一个构造函数).

2.拷贝构造函数的参数只有一个且必须是类类型的引用,使用传值方式编译器直接报错,因为会引发无穷递归调用。

那么为什么传值方式会引发无穷递归呢?

那么我相信大家肯定会有疑惑,为什么在C语言中我传结构体的时候能够传过去呢,这个嘛.....呃呃, 欢迎各位大佬在评论区下方留言,小编也挺好奇的。那么正确的拷贝构造函数方式是什么呢?
正确的方式应该是用引用接收,其实引用的最底层逻辑也是指针,通过引用就能直接找到地址里的内容,但是引用比指针简单,而且更容易理解
接下来跟大家讲编译器默认生成的拷贝构造,在一些场景下可能会出现异常的情况
大家先看我的这段代码, 因为有编译器默认生成的拷贝构造,而且所以的类型都是自定义类型,结果是能够完成拷贝任务的,我们把这种拷贝叫做浅拷贝,再来看一段代码
那么这段代码会正常运行吗? 答案是不会,因为指针也是内置类型,所以编译器在调用默认的拷贝构造的时候就会把指针中的地址赋给新创建的指针,两个指针就会指向同一块地址,但是这不是导致程序奔溃的原因,最根本的原因在于我们在程序结束时需要调用析构函数,那么就会调用2次析构函数,对同一块地方同时进行两次free就会造成程序奔溃,那么我们想要完成这种拷贝就需要深拷贝,深拷贝就需要我们自己写,把指针中的内容手动拷贝到新指针开辟的空间中。
那么,我们什么时候应该写拷贝构造函数呢,当我们的程序涉及到资源申请时,就比如说我向操作系统要了空间等,我们就需要自己写拷贝构造函数。
拷贝构造函数典型调用场景:
使用已存在对象构建新对象。
函数参数类型为类类型对象
函数返回值类型为类类型对象。
红框框中的两种都算是拷贝构造。
这种类型就是第二种,函数参数类型为类类型对象
这种就是第三中,函数返回值为类类型对象。
还有一些内容我们留到下一期再讲,感谢大家的观看和支持!
  • 25
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ZENG zhi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值