C++程序设计——类的六个成员函数

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

类的六个成员函数

 空类中真的什么都没有吗

        事实上任何一个类在我们不写的情况下都会自动生成6个默认的成员函数。

1.构造函数

概念

        构造函数是一个特殊的成员函数名字与类名相同实例化对象时由编译器自动调用以此来保证每个数据成员都有一个合适的初始值并且在对象的生命周期内只调用一次

构造函数的主要作用是初始化对象不是开辟空间创建对象

特征

1.函数名与类名相同

2.创建对象时由编译器自动调用用户无法调用

3.无返回值void也不可以

4.构造函数可以重载

5.若类中没有显式定义构造函数则编译器会自动生成一个无参的默认构造函数若用户已显式定义则编译器不再生成

6.无参和全缺省的构造函数都称为默认构造函数且默认构造函数只能有一个

例1

 

例2

例3

 

2.析构函数

概念

        与构造函数相反析构函数不是完成对象的销毁局部对象销毁工作是由编译器完成的而对象在销毁时会自动调用析构函数完成类的一些资源清理工作。

特性

1.析构函数名是在类名前加上一个字符‘~’。

2.没有参数可以加void但一般不会这样使用没有返回值。

3.一个类有且仅有一个析构函数不能重载。若未显式定义系统则会自动生成默认的析构函数。

4.对象生命周期结束时C++编译系统会自动调用析构函数。

默认的成员函数一定会生成

        从语法上来讲是一定会生成的但是实际情况中并不一定。因为语法是靠人来具体实现的有时需要考虑一些其他因素比如程序的运行效率所以有可能不会严格按照语法来实现。

        比如一下代码并没有什么意义在某些编译器及版本中例VS2013就不会生成类的默认成员函数。

3.拷贝构造函数

概念

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

特征

1.拷贝构造函数是构造函数的一个重载形式

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

3.若未显式定义系统会生成默认的拷贝构造函数。

注意默认的拷贝构造函数对象按内存存储按字节序完成拷贝这种拷贝属于浅拷贝或叫值拷贝所以没有涉及到资源管理可以直接使用默认的拷贝构造函数。

为什么拷贝构造函数使用传值方式会引发无穷递归

        那我们就假设可以使用传值方式那么在调用拷贝构造函数时就会发生临时拷贝需要将实参拷贝到形参中即通过实参来构造形参对象那么此时就又需要调用拷贝构造函数因此陷入无穷递归调用。

什么情况需要自实现拷贝构造函数

        因为默认的拷贝构造函数采用的是浅拷贝因此当涉及到资源的管理时就需要自实现拷贝构造函数。

调用拷贝构造函数的场景

1用一个对象直接构造一个新对象

2类类型对象以值的形式传参

3类类型对象以值的方式作为函数返回值

注意若直接创建返回一个匿名对象编译器不会通过拷贝构造函数创建一个临时对象返回而是直接将匿名对象返回。

4.赋值运算符重载

概念

        C++为了增强代码的可读性引入了运算符重载运算符重载是具有特殊函数名的函数也具有其返回值类型、函数名以及参数列表其返回值类型与参数列表和普通的函数类似。

函数名关键字operator后面接需要重载的运算符符号

函数原型返回值类型  operator操作符参数列表

注意

1.不能通过连接其他符号来创建新的操作符比如operator@

2.重载操作符必须有一个类类型或者枚举类型的操作数

3.用于内置类型的操作符其含义不能改变例如内置的整型+不能改变其含义

4.作为类成员的重载函数时其形参看起来比操作数数目少一其实成员函数的操作符有一个默认的形参this限定为第一个参数

5.以下五个运算符不能重载.*、::、sizeof、?:、.

什么情况需要自实现赋值运算符重载

        默认的赋值运算符重载也是采用的浅拷贝所以如果类中未涉及到资源管理时赋值操作是否显示提供都可以需要则提供不需要则可不提供利用编译器完成赋值操作即可。

        若类中涉及到资源管理则用户必须显示实现否则编译器默认生成的赋值运算符重载实现采用的是浅拷贝可能造成资源、内存泄漏和多个对象共享同一份资源在销毁时造成代码崩溃。

为什么赋值运算符重载必须重载为类的成员函数

        因为赋值运算符重载是类默认的成员函数若用户没有显示定义时编译器会自动生成一份而此时若用户自己再在类外实现一份相等于存在两个赋值运算符重载形成歧义编译器则会报错。

较为标准的赋值运算符重载

1加返回值支持连续赋值

        类类型对象赋值相当于是调用赋值运算符重载函数结合连续赋值的本质所以需要对赋值运算符重载函数加返回值。

2返回引用前提不影响功能实现提高效率

        返回引用则返回时不需要再调用拷贝构造函数构造临时对象提高程序效率。

3引用传参提高效率

4const修饰参数防止参数对象被修改

5添加检验防止本身给本身赋值

实现重载前置++与后置++

        因为++运算符是单目运算符作为类的成员重载函数自带了默认的形参this所以为了能够实现前置与后置++重载可以选择在其中一个重载函数中多加一个形参作为区分

注意

        后置++是先使用再+1。所以需要先临时保存对象再对对象数据+1然后返回的是+1前的临时对象即这里不可以返回引用。

5.const成员函数

const修饰类的成员函数

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

        比如以下函数本意只是想对时间进行一个打印输出但是在内部可能不小心会对数据造成修改影响功能实现

this的类型Time* const this

即this指针的指向不能修改但是this指向对象中的内容可以修改。

        此时就可以通过const修饰该成员函数表明在该成员函数中不能对类的任何成员进行修改。

this的类型const Time* const this

即this指针的指向不能修改指向对象中的内容也不能修改。

相关问题

1const对象能否调用非const成员函数

        不能const类型对象只能调用const成员函数不能调用普通成员函数。因为普通成员函数可能会对对象中的成员进行修改。

2非const对象能否调用const成员函数

        可以普通对象对于普通成员函数和const成员函数都可以调用。

3const成员函数内能否调用其他的非const成员函数

        不能同理非const成员函数可能会对对象的成员进行修改而const成员函数内不能对对象的任何成员进行修改。

4非const成员函数内能否调用其他的const成员函数

        可以。

注意

        构造函数拷贝构造函数析构函数赋值运算符重载不可以使用const修饰。因为以上四个函数目的就是对成员进行修改。

mutable关键字

        mutable关键字修饰成员变量表示该成员变量可以在const修饰中被修改。

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

取地址操作符重载

 

const取地址操作符重载

注意

        这两个运算符一般使用编译器生成的默认取地址重载成员函数即可一般不需要自己实现重载。只有特殊情况才需要自己实现比如想要让别人获取指定的内容等。

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: c++