• 从零开始的C++(五)


    1.类和对象的补充

    当对象是const修饰的常量时,形参中的this是隐含的,那么该如何写函数才能传常量对象呢?如果还是按照正常的方式写,则会出现实参是const修饰的,形参没有,出现了权限的扩大,无法使用。因此需要在括号和大括号之间加一个const,这个const是专门修饰this指针的。

    如上图的d1是const修饰的,调用d1的成员函数print,print加了一个const修饰this指针。

    如果把const放函数最前面,则const修饰的是函数的返回值,但由于函数的返回值一般会经过一次拷贝拷贝到一个临时常量,在把这个临时常量赋值给实际接受的变量,而临时常量具有常性,因此加与不加const此时无影响。但有一种情况下前面加const会有影响,就是返回的是引用,此时不会拷贝返回值到一个临时常量,而const此时的作用是使得返回的那个变量无法被修改。

    const修饰this指针的时候,与不加const修饰this指针构成了函数重载,此时非const修饰的对象两个函数都可以调用,const修饰的只能调用有const的函数。但如果有和没有const修饰的函数均有,非const修饰的对象会调用哪一个?答案是调用更适配的那个,即非const优先调用没有const的函数,如果只有有const的函数,则也可以调用有const的函数。

    const修饰this指针,此时const的作用只有对象的成员,但如果对象的成员有指针,此时修改指针指向的对象的值是可以的,但一般根据逻辑上我们是不希望可以修改的,所以此时对返回值加const可以起到作用。

    总结一下上文,一般不希望形参被修改的时候,会加一个const修饰this指针,例如比较大小的运算符重载往往需要加const。

    2.默认成员函数:

    取地址运算符:不写的时候编译器会默认生成一个,作用是取首地址。可以进行运算符重载。重载的有const修饰this和非const修饰this的两种。一般用不到,只有在不希望地址被获取的时候才用。

    3.类外调用私有成员的方法:

    友元函数:非成员函数,但需要把函数声明放在类声明里,并在函数声明最前面加一个friend,声明其是友元函数,此时函数可以调用类内的私有成员。

    4。流插入和流删除:

    流(stream),做输入和输出的中转站,通过重载流插入和流删除的运算法,可以实现cout、cin跟自定义类型的对象。

    请注意,重载这两个函数不能做成员函数,因为成员函数的第一个参数一定是this指针,不符合此处的顺序(即此处第一个参数应该是流,第二个参数才是对象),而在类外需要调用私有成员的时候就需要声明友元函数,所以此处重载的两个函数均是友元函数。考虑到连续调用该运算符的情况,所以函数的返回类型是流的引用。

    5.初始化列表:

    形式:以冒号开始,逗号分隔,每个成员变量后跟一个括号,括号内是要赋的初值。

    此处对_year、_day进行了初始化列表,实现了把year赋给_year,day赋给_day.

    本质:对所有的对象成员进行定义的地方(注意所有和定义),如果初始化列表里没有该对象成员,则相当于赋了随机值。

    当成员是const修饰的或者是引用的时候,必须用初始化列表,因为const和引用需要在定义阶段初始化赋值。但需要注意static修饰的不用,因为静态的要在类外初始化。所以static修饰的const类型的不一定要用初始化列表。(注意此处是不一定不是不能!)

    自定义类型的对象做成员的时候,可以在初始化列表里进行带参数的拷贝。

    初始化列表可以不写,此时内置类型不处理,自定义类型调用默认构造函数。初始化列表也可以只写一部分成员变量。

    声明阶段的缺省值实质就是写初始化列表,此时如果初始化列表没有该变量,则调用缺省值。同时,初始胡列表的实际调用顺序就是变量的声明顺序(此时需要注意,有时候在初始化列表中将一个成员变量赋给另一个成员变量时,需要考虑两个变量的声明顺序,不然可能会出现还是随机值的时候就把变量赋给另一个变量了)。

    初始化列表中每个成员只能出现一次。

    自定义类型的成员会强制去初始化列表中调用,此时初始化列表有则调用值拷贝,没有则调用默认拷贝。

    6:单参数的构造函数隐式类型转换(注意成员只能有一个!!)

    形如 “类名 对象名=内置类型的值”,此处是先将内置类型的拷贝赋值给一个与对象同类型的临时变量,在用拷贝构造把临时变量赋给对象。但在编译器中优化成了一步直接拷贝。

    如果d1是引用类型则必须加const,因为临时变量具有常性。

    隐式转换的好处:可以不用先用值拷贝的方式创建一个对象,在把这个对象拷贝赋值给另一个对象,写起来更加方便。

    如果d1中有多个参数,则等号右侧的参数用"{}"括起来,用逗号分隔。

    匿名对象:

    形如类名(值),生命周期只有一行,一般用于赋值时化简。

    总结:本篇补充了类和对象,介绍了取地址运算符的重载、初始化列表、流插入和流删除、友元函数、单参数隐式类型转换、匿名对象。

  • 相关阅读:
    电脑如何不断网切换IP:实用方法与注意事项‌
    vant_vant引入
    cmake下的abiFilters和ndk下的abiFilters的区别
    vue接口token认证登录(加手机验证)
    全面升级 | 两行代码,轻松搞定登录系统
    Exception : Content-Type cannot contain wildcard type ‘*‘
    AOP基础知识了解
    CSDN第11期周赛题解
    计算机网络
    从零搭建一个PWA应用需要了解哪些知识
  • 原文地址:https://blog.csdn.net/yyssas/article/details/133606079