C++学习--类与对象(中)

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

2.构造函数

3.析构函数

4.拷贝构造函数

5.赋值操作函数

6.默认拷贝构造函数与赋值运算符重载函数

7.const成员函数

8.取地址及const取地址操作符重载


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

初接触类的时候,我们写过空类,那么空类真的是什么都没有吗?其实不是的

在我们不人为实现的时候,任何类都会有如下6个默认成员函数

2.构造函数

2.1概念

对于类A,我们如果想对A的实例化对象设置内容可以通过setval来实现,但我们要先创建出A,

再进行调用,这样过于繁琐,那么构造函数就是一种特殊的成员函数,名字与类名相同且没有返回类型,创建对象的时候编译器会自动调用,并且在一个对象的生命周期内只调用一次

 

 

 2.2特性

构造函数是特殊的成员函数,虽然名字叫构造,但并不是开辟空间而是对成员的初始化

其特征如下:

1.函数名与类名相同

2.无返回值

3.对象实例化时编译器自动调用对应的构造函数

4.构造函数可以重载

如果没有人为给出,编译器默认生成无参默认构造函数,人为给出任意形式的构造函数,编译器都不会生成默认无参构造函数

2.3 初始化列表

前面我们说构造函数只是对成员的初始化,初始化的这一操作我们可以在函数内直接实现(这是我们所熟知的),但是C++提供了另一种效率更高的方式,即初始化列表

使用方式如下

需要注意的是:

1.初始化列表的赋值顺序为declare的顺序,即 _x , _y ,_z 哪怕我们代码顺序为_z,_y,_x仍然会以declare顺序进行初始化,明晰这一点可以避免一些不必要的bug

 2.初始化列表这一操作为defination,函数体内操作为assignment

3.析构函数

2.1概念

C语言学习中我们都写过链表,栈和队列,我们总要实现Init和Destory函数并通过函数的调用来进行空间的开辟和回收,构造函数的出现显然省去了Init这一函数的调用,C++肯定不会只满足于这一点,与构造函数对应,析构函数应运而生

析构函数:与构造函数相反,析构函数并不是进行对象的销毁,对于局部对象,编译器在其生命周期结束时自动销毁,但是会先调用其析构函数,完成类的一些资源清理工作

2.2特性

特征如下:
1. 析构函数名是在类名前加上字符 ~。
2. 无参数无返回值。(不能重载)
3. 一个类有且只有一个析构函数。若未显式定义,系统会自动生成默认的析构函数。
4. 对象生命周期结束时,C++编译系统系统自动调用析构函数。

 

 对于对象的构造和析构也遵循压栈弹栈的顺序,先创建的在栈底,栈顶的先析构

4.拷贝构造函数

4.1概念

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

4.2特性

1. 拷贝构造函数是构造函数的一个重载形式。
2. 拷贝构造函数的参数只有一个且必须使用引用传参,使用传值方式会引发无穷递归调用。

3. 若未显示定义,系统生成默认的拷贝构造函数。 默认的拷贝构造函数对象按内存存储按字节序完成拷贝,这种拷贝我们叫做浅拷贝,或者值拷贝

拷贝构造会对内置类型完成浅拷贝或者值拷贝,对自定义类型成员会调用它们自己的拷贝构造函数

我们发现由a1拷贝构造的a2指针对象data的地址相同,因而导致了析构时重复delete的错误,所以系统默认的拷贝构造函数只完成了浅拷贝

改用如下代码后程序正常运行

 

5.赋值操作函数

赋值操作符重载

C++为了增强代码的可读性引入了运算符重载,运算符重载是具有特殊函数名的函数,也具有其返回值类型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似。
函数名字为:关键字operator后面接需要重载的运算符符号。
函数原型:返回值类型 operator操作符(参数列表)
注意:
不能通过连接其他符号来创建新的操作符:比如operator@
重载操作符必须有一个类类型或者枚举类型的操作数
用于内置类型的操作符,其含义不能改变,例如:内置的整型+,不能改变其含义
作为类成员的重载函数时,其形参看起来比操作数啊目少1成员函数的操作符有一个默认的形参this,限定为第一个形参
.* 、:: 、sizeof 、?: 、. 以上5个运算符不能重载。必须要记住。
内置类型:语言层面就支持运算符
自定义类型:编译器默认不支持,c++可以用运算符重载让类对象支持用某个运算符

6.默认拷贝构造函数与赋值运算符重载函数

 

上述操作我们发现系统又报错了,说明编译器默认给的赋值函数为浅拷贝,

 

代码改写后运行正常

需要注意的地方:

1.引用传参 , 避免拷贝构造

2.引用返回,为了支持连续赋值操作

3.判断是否是自己给自己赋值,避免delete自己的成员后无法正确赋值

7.const成员函数

之前学习函数重载知道了const可以作为重载的区分条件,那么什么是const成员函数?

7.1概念

将const修饰的类成员函数称之为const成员函数,const修饰类成员函数,实际修饰该成员函数隐含的this指针,表明在该成员函数中不能对类的任何成员进行修改。

7.2 使用

 

 我们发现const A类型的a2调用show函数失败了,因为原先this的类型是A* const , 这就导致了参数类型不匹配,当我们加入const修饰的show后,const修饰的show的隐含this类型为const A* const ,这样程序再次正常运行

8.取地址及const取地址操作符重载

通过前面对于const成员函数的修饰,我们不禁会想为什么对于const对象取地址我们并没有重载对应的const函数但仍然取地址成功了呢?

这两个默认成员函数一般不用重新定义 ,编译器默认会生成

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

EQUINOX1

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

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

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

打赏作者

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

抵扣说明:

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

余额充值