• 类和对象(下)



    1. 再谈构造函数

    1.1初始化列表

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

    class Date
    {
    public:
    	Date(int year, int month, int day)
    	: _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

    使用初始化列表的好处:使用初始化列表少了一次调用默认构造函数的过程,并且对于以下成员,必须放在初始化列表位置进行初始化。

    • 引用成员变量
    • const成员变量
    • 自定义类型成员(该类没有默认构造函数)

    结论:自定义类型、内置类型的成员,都推荐使用初始化列表初始化

    1.2 explicit关键字

    构造函数不仅可以构造与初始化对象,对于单个参数的构造函数,还具有类型转换的作用。
    用explicit修饰构造函数,将会禁止单参构造函数的隐式转换。
    这个我们在讲string时再细说。

    2. static成员

    2.1 概念

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

    2.2 特性

    1. 静态成员为所有类对象所共享,不属于某个具体的实例
    2. 静态成员变量必须在类外定义,定义时不添加static关键字
    3. 类静态成员即可用类名::静态成员或者对象.静态成员来访问
    4. 静态成员函数没有隐藏的this指针,不能访问任何非静态成员
    5. 静态成员和类的普通成员一样,也有public、protected、private3种访问级别,也可以具有返回值

    3. 友元

    友元分为:友元函数和友元类
    友元提供了一种突破封装的方式,有时提供了便利。但是友元会增加耦合度,破坏了封装,所以友元不宜多用。

    3.1友元函数

    友元函数是指某些虽然不是类成员函数却能够访问类的所有成员的函数。类授予它的友元特别的访问权,这样该友元函数就能访问到类中的所有成员。
    友元函数可以直接访问类的私有成员,它是定义在类外部的普通函数,不属于任何类,但需要在类的内部声明,声明时需要加friend关键字。

    class Date
    {
    	friend ostream& operator<<(ostream& _cout, const Date& d);
    	friend istream& operator>>(istream& _cin, Date& d);
    public:
    	Date(int year, int month, int day)
    	: _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

    上文加了friend后,operate重载的函数便可正常使用。

    3.2友元类

    友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员。

    1. 友元关系是单向的,不具有交换性。
    2. 如果B是A的友元,C是B的友元,则不能说明C时A的友元。

    如下面的Date为Time的友元类。

    class Date; // 前置声明
    class Time
    {
    	friend class Date; 
    public:
    	Time(int hour, int minute, int second)
    	: _hour(hour)
    	, _minute(minute)
    	, _second(second)
    	{}
    private:
    	int _hour;
    	int _minute;
    	int _second;
    };
    class Date
    {
    public:
    	Date(int year = 1900, int month = 1, int day = 1)
    	: _year(year)
    	, _month(month)
    	, _day(day)
    	{}
    	void SetTimeOfDate(int hour, int minute, int second)
    	{
    	// 直接访问时间类私有的成员变量
    		_t._hour = hour;
    		_t._minute = minute;
    		_t.second = second;
    	}
    private:
    	int _year;
    	int _month;
    	int _day;
    	Time _t;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    4. 内部类

    如果一个类定义在另一个类的内部,这个内部类就叫做内部类。注意此时这个内部类是一个独立的类,它不属于外部类,更不能通过外部类的对象去调用内部类。外部类对内部类没有任何优越的访问权限。

    内部类就是外部类的友元类。注意友元类的定义,内部类可以通过外部类的对象参数来访问外部类中的所有成员。但是外部类不是内部类的友元。

    特性:
    1. 内部类可以定义在外部类的public、protected、private都是可以的。
    2. 注意内部类可以直接访问外部类中的static、枚举成员,不需要外部类的对象/类名。
    3. sizeof(外部类)=外部类,和内部类没有任何关系


    总结

    以上就是今天要讲的内容。
    在这里插入图片描述

  • 相关阅读:
    linux实现tcp工具
    C++笔记
    中国行李箱市场深度全景调研及投资前景分析报告
    AtCoder Beginner Contest 357
    【老生谈算法】matlab实现图像滤波处理算法源码——图像滤波处理算法
    索引(1)
    LSTM缓解梯度消失问题
    专注写作,快速上线:Cpolar+Inis帮助你在Ubuntu上建立博客网站
    拼多多第二季度表现亮眼,“贪便宜”的你贡献了多少?
    EMQX启用双向SSL/TLS安全连接以及java连接
  • 原文地址:https://blog.csdn.net/m0_63742310/article/details/126853465