发布时间:2025-06-24 18:04:15  作者:北方职教升学中心  阅读量:673


  • 而且我们在类里面去给其他类进行使用缺省值的时候也是非常方便
classC{public://explicit C(int x = 0)C(intx =0):_x(x){}C(constC&cc){cout <<"C(const C& cc)"<<endl;}private:int_x;};C xx(1);//定义全局变量来赋缺省值classB{private:// 缺省值inta =1;int*p1 =nullptr;int*p2 =(int*)malloc(4);C cc1 =xx;// 虽然可以,但是很费劲C cc2 =2;};
  • push 插入时直接使用隐式类型转换,不需要在插入相同类型的类了
classC{public://explicit C(int x = 0)C(intx =0):_x(x){}C(constC&cc){cout <<"C(const C& cc)"<<endl;}private:int_x;};classStack{public:voidPush(constC&c){//}};intmain(){Stack st;C cc3(3);st.Push(cc3);st.Push(4);return0;}

4.2 explicit关键字的使用

explict的关键字是用来修饰构造函数的一旦使用了 explicit修饰构造函数,禁止类型转换
在这里插入图片描述

classA{public:explicitA(intx){cout <<"A()"<<endl;}~A(){cout <<"~A()"<<endl;}private:int_x;};classData{public:explicitData(intyear,intmonth =10,intday =1){cout <<"data()"<<endl;}~Data(){cout <<"~data()"<<endl;}private:int_year;int_month;int_day;};intmain(){A a1 =2;Data a2 =2020;return0;}

在这里插入图片描述

classData{public:Data(intyear,intmonth =10,intday =1){cout <<"data()"<<endl;}~Data(){cout <<"~data()"<<endl;}private:int_year;int_month;int_day;};intmain(){Data a1(2021);Data a2 =2022;return0;}

4.2 隐式转换的作用

隐式转换可以说是非常的好用了以后我们在很多地方都可以用到,以往我们使用链表存储类的话每次push都需要,push成员变量,但是有了隐式类型转换就可以直接插入自动转换为我们需要的类了。
2. 在成员函数里如果我们要对成员变量进行修改,不能加上 cosnt指针。

文章目录

  • 引入
  • ⛳️ 推荐
  • 一、
classDate{public:Date(intyear,intmonth,intday):_year(year),_month(month),_day(day){}private:int_year;int_month;int_day;};
  1. 每个成员变量在初始化列表中只能出现一次(初始化只能初始化一次)
  2. 类中包含以下成员,必须放在初始化列表位置进行初始化:
  • 引用成员变量
  • const成员变量
  • 自定义类型成员(且该类没有默认构造函数时)

规则一

  • 尽量使用初始化列表初始化,因为不管你是否使用初始化列表,对于自定义类型成员变量,一定会先使用初始化列表初始化。const 成员函数

    1.1 什么是const 成员函数

    cosnt 的成员函数其实就是在我们 函数的括号外多加一个 constvoid Dlsplay() const

    • 其他的作用是修饰 隐含的 this指针,使其不能修改。取地址及const取地址操作符重载
      • 2.1 取地址操作的意义
    • 三、

      在这里插入图片描述

      🎬 鸽芷咕:个人主页

       🔥 个人专栏: 《C++干货基地》《粉丝福利》

      ⛺️生活的理想,就是为了理想的生活!

      引入

        哈喽各位铁汁们好啊,我是博主鸽芷咕《C++干货基地》是由我的襄阳家乡零食基地有感而发,不知道各位的城市有没有这种实惠又全面的零食基地呢?C++ 本身作为一门篇底层的一种语言,世面的免费课程大多都没有教明白。

      classA{public:A(intx){this->_x =x;cout <<"A()"<<endl;}~A(){cout <<"~A()"<<endl;}private:int_x;};intmain(){A a1(1);A a2 =3;return0;}

      这里我们既可以使用构造函数来进行赋值,还可以使用隐式类型转换的方法来进行赋值。

    这个我相信很好了解,初始化列表不管我们写没写都会在初始化列表进行初始化

    • 所以对于简单的变量初始化建议使用初始化列表
    • 一些复杂的类初始化可以使用在构造函数体内进行初始化

    规则二

    • 成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后次序无关

    🍸 代码演示:

    classA{public:A(inta):_a1(a),_a2(_a1){}voidPrint(){cout<<_a1<<" "<<_a2<<endl;}private:int_a2;int_a1;};intmain(){A aa(1);aa.Print();}
    • 大家猜一猜这个程序运行会出现什么情况呢?

    • A. 输出1 1B.程序崩溃

    • C.编译不通过D.输出1 随机值

    这里的答案是选D
    虽然我们在初始化列表先写的是 _a1但是初始化列表是按照声明的顺序来进行初始化的,对 _a2(_a1)进行初始化的时候 __a1还是一个随机值,_a2就被赋值成了 _a1的随机值

    四、点击跳转到网站。取地址及const取地址操作符重载

    2.1 取地址操作的意义

    取地址操作符顾名思义,就对我们的 &取地址符号进行重载使其能获取到成员变量的地址

    • 但是一般都是默认生成的,除非我们想让取地址符号取的是指定位置的地址
    classDate{public:Date*operator&(){returnthis;}constDate*operator&()const{returnthis;}private:int_year;// 年int_month;// 月int_day;// 日};

    三、

  • 所以构造函数并不是初始化成员变量的地方,而我们在进行类声明的时候给的的默认值夜也只是声明

3.2 初始化列表

在C++中规定了所有成员变量在初始化的时候都是在初始化列表进行初始化的

  • 初始化列表:以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个"成员变量"后面跟
    一个放在括号中的初始值或表达式。重新认识构造函数
    • 3.1构造函数体赋值
    • 3.2 初始化列表
      • 规则一
      • 规则二
  • 四、

    • 其主要原理是 使用 =号赋值时,会先用 1 构造一个临时变量然后再调用拷贝构造构造函数
    • 也就是 先构造->在拷贝构造

    但是编译器目前太智能了,对同一个表达式连续的构造会合二为一优化为一步
    在这里插入图片描述

    • 除第一个参数无默认值其余均有默认值的构造函数,还具有类型转换的作用。重新认识构造函数

      3.1构造函数体赋值

      以往我们在定义构造函数的时候都是在构造函数内进行赋值的,那么我们创建成员变量是否也是在构造函数里面呢?

      • 如果构造函数是创建的话那么,我们声明成员变量的时候给的默认值是定义嘛?
      classDate{public:Date(intyear,intmonth,intday){_year =year;_month =month;_day =day;}private:int_year =2022;int_month =06;int_day =25;};
      • 构造函数体中的语句只能将其称为赋初值,而不能称作初始化。explicit关键字

        4.1 构造函数的隐式类型转换

        构造函数不仅可以构造与初始化对象,对于单个参数或者除第一个参数无默认值其余均有默认值
        的构造函数,还具有类型转换的作用。

        ⛳️ 推荐

        前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。因为初始化只能初始化一次,而构造函数体内可以多次赋值。

在这里插入图片描述

1.2 const成员函数的注意事项

const 成员可以直接修饰this指针那么使用起来有什么要注意的嘛?

  • 下面我们看一下这些代码来思考一下
#include<iostream>usingnamespacestd;classDate{public:Date(intyear,intmonth,intday){_year =year;_month =month;_day =day;}voidPrint(){cout <<"Print()"<<endl;cout <<"year:"<<_year <<endl;cout <<"month:"<<_month <<endl;cout <<"day:"<<_day <<endl <<endl;}voidPrint()const{cout <<"Print()const"<<endl;cout <<"year:"<<_year <<endl;cout <<"month:"<<_month <<endl;cout <<"day:"<<_day <<endl <<endl;}private:int_year;// 年int_month;// 月int_day;// 日};voidTest(){Date d1(2022,1,13);d1.Print();constDate d2(2022,1,13);d2.Print();}intmain(){Test();return0;}
  1. const对象可以调用非const成员函数吗?
  • 不能 const 对象调用非const成员会导致,权限的放大所以会出现错误
  1. 非const对象可以调用const成员函数吗?
  • 可以 非const 成员调用 const 成员函数属于权限的缩小,权限是可以缩小的
  1. const成员函数内可以调用其它的非const成员函数吗?
  • 不可以,这样会导致权限的放大
  1. 非const成员函数内可以调用其它的const成员函数吗?
  • 可以,非const 成员,调用const 成员是权限的缩小

总结

1. 在成员函数里如果我们只对成员变量读访问,那么建议加上 cosnt指针。explicit关键字

    • 4.1 构造函数的隐式类型转换
    • 4.2 隐式转换的作用
    • 4.2 explicit关键字的使用
  • 一、所以本篇专栏的内容全是干货让大家从底层了解C++,把更多的知识由抽象到简单通俗易懂。(否者修改不了成员变量)

    二、const 成员函数
    • 1.1 什么是const 成员函数
    • 1.2 const成员函数的注意事项
    • 总结
  • 二、