• 【C++】类和对象(四)“这三种”成员变量只能放在初始化列表中初始化,你都知道吗?


    🧸🧸🧸各位大佬大家好,我是猪皮兄弟🧸🧸🧸
    在这里插入图片描述

    一、初始化列表

    初始化列表:以冒号开始,以逗号分隔的数据成员列表,每个成员变量跟一个放在括号中的初始值或表达式

    class Date
    {
    public:
    	Date(int year=1,int month=1,int day=1)
    		:_year(year)
    		,_month(month)
    		,_day(day)
    	{
    	}
    	
    private:
    	int _year;
    	int _month;
    	int _day;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    注意事项:
    1.每个成员变量在初始化的时候只能出现一次(初始化只能初始化一次)
    2.类中出现以下成员,只能在初始化列表中进行初始化,原因在下面
        a.引用成员变量
        b.const成员变量
        c.自定义类型成员,且该类没有默认构造(也就是说必须传参)

    默认构造包括三种
    编译器自己生成,自己写的无参和全缺省

    class Time
    {
    public:
    	Time(int hour)
    	{
    		_hour=hour;
    	}
    private: 
    	int _hour;
    };
    class Date
    {
    public:
    	Date(int year,int hour)
    		:_year(year)
    		,_t(hour)//没有默认构造函数
    	{
    	}
    	
    private:
    	int _year;
    	Time _t;//对自定义类型的变量处理是调用Time的默认构造(三种之一)
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    如果像这么做:
    在这里插入图片描述
    在这里插入图片描述

    在调用构造函数的时候所有的成员变量都要先走一遍初始化列表进行定义,同时可以在初始化列表进行初始化。首先,只有在实例化时调用构造函数走进初始化列表才算是定义成员变量,不然都是声明而已,其次,像无默认构造函数的Time,不在初始化列表中去写的话因为没有给参数,所以会报错(就是因为在初始化列表中定义和初始化的,函数体内最多算是在重新赋值)
    总的来说就是所有的成员变量都在初始化列表中进行定义和初始化!!

    二、explicit关键字

    int i=10;
    const double &d = i;
    中间会产生一个临时变量,d引用的是这个临时变量,而不是i
    而且这个临时变量具有常性,所以d需要加上const修饰
    
    • 1
    • 2
    • 3
    • 4
    class Date
    {
    public:
    	/*explict*/Date(int year)
    	{
    		_year=year;
    	}
    
    private:
    	int _year;
    };
    int main()
    {
    	Date d = 2022;
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    Date d =2022;从int转换到了date说明发生了隐式类型转换,这种隐式类型的转换是(构造+拷贝构造+优化)如果想防止这种隐式类型转换发生,那么加上关键字explicit

    三、匿名对象

    匿名对象因为没有名字,所以生命周期会非常短,只在这一行

    class Date
    {
    public:
    	Date(int year=1)
    	{
    		_year=year;
    	}
    private:
    	int _year;
    };
    int main()
    {
    	Date(2000);//生命周期只在这一行
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    四、static静态成员

    声明为static的类成员,称为类的静态成员,用static修饰的成员变量,称为静态成员变量,用static修饰的成员函数,称为静态成员函数,静态成员变量需要在类外进行初始化

    class Date
    {
    
    private:
    	static int a;
    	static int arr[3];
    };
    int Date::a=10;
    int Date::arr[3]= {1,2,3}; 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    注意事项:
    1.其他的成员变量都是放在初始化列表定义的,但是静态成员变量不行
    2.静态成员变量的缺省值是给初始化列表的,但是静态成员并不在初始化列表中定义,所以静态成员变量不给缺省值

    class Date
    {
    private:
    	int a=10;//这是缺省值,a在这里是声明,因为没有开空间
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5

    静态成员特征:
    1.静态成员由所有类对象所共享,不属于某个具体的对象,存放在静态区(包括静态成员变量和静态成员函数)
    2.静态成员必须在类外定义和初始化,定义时不添加static关键字,类中只是声明,不管共有还是私有,都是在类外定义和初始化
    3.静态成员函数没有this指针,所以无法访问某个具体对象的成员变量或者方法,只能去访问静态成员

    五、友元(能少用就少用,破坏封装)

    高内聚,低耦合
    友元提供了一种突破封装的方式,有时提供了便利,但是友元会增加耦合度,破坏了封装,所以友元不宜多用

    友元的特性:
    1.友元函数可以访问类的私有 和保护成员,但是友元函数不是成员函数
    比如上一节讲的流插入<<和流提取>>
    2.友元函数不能用const修饰
    3.友元函数的定义可以在类的人和地方定义,不受访问限定符的影响,习惯定义在最上面。
    4.一个函数可以是多个类的友元函数,只要friend就可以
    5.友元函数的调用和类外普通函数的调用类似,只不过是函数重载,可以去调用私有和保护而已

    在这里插入图片描述

    六、友元类

    友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的私有和保护
    1.友元关系是单向的,不具有交换性(想交换就两个friend)
    2.友元关系不能传递,不能A–>B B–>C C不>A
    3.友元关系不能继承

    七、内部类

    内部类:如果一个类定义在一个类的内部,这个内部类就叫做内部类,内部类是一个独立的类,它不属于外部类,更不能通过外部类的对象去访问内部类的成员,外部类对内部类没有任何优越的访问权限。
    其实就跟在在类外定义了一个类一样,但是有两点不同
    1.受外部类类域的限制
    2.内部类天生是外部类的友元,但是外部类不是

    特征:
    1.内部类定义在外部类的public,protected,private都是可以的
    2.内部类可以直接去访问外部类中的static成员,不需要通过对象/类名
    3.sizeof(外部类)==外部类的大小,与内部类没有关系

    八、总结

    上面对C++类和对象剩下重要知识点进行了总结,感谢大家的支持,类和对象的内容就更新完了,后面我会继续更新内存管理有关方面的内容!
    在这里插入图片描述

  • 相关阅读:
    操作系统进程调度算法的模拟实现(c语言版本)
    故障电弧探测器的必要性及组网方案 安科瑞 时丽花
    i5 12600HX比i5 12600H选哪个好
    PMP 11.27 考试倒计时8天!
    关于使用Mxnet GPU版本运行DeepAR报错解决方案
    es(Elasticsearch)安装使用(03ik分词器安装篇)
    新学期,新FLAG
    《下一代互联网(IPv6)搭建与运维》
    荒野大镖客emp.dll文件丢失的怎么办,快速修复游戏dll问题
    Java + Selenium + Appium自动化测试
  • 原文地址:https://blog.csdn.net/zhu_pi_xx/article/details/126631527