• 类和对象(8):explicit,static成员,友元,内部类


    一、explicit

    class Date
    {
    public:
    	Date(int year = 2023, int month = 1, int day = 1)
    		:_year(year)
    		,_month(month)
    		,_day(day)
    	{}
    
    private:
    	int _year;
    	int _month;
    	int _day;
    };
    
    
    int main()
    {
        // Date d1(1); // 这是正常初始化
    	Date d1 = 1;
    
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    不妨猜测一下,d1的初始化结果是什么?

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

    explicit修饰构造函数,将会禁止构造函数的默认转换。

    二、static成员

    2.1 概念

    声明为static的类成员,称为类的静态成员(静态成员变量或静态成员函数)静态成员变量一定要在类外初始化

    class A
    {
    private:
    	static int _a;// 声明
    };
    
    int _a = 0;// 初始化
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    2.2 特性

    1. 静态成员所有类对象共享,存在静态区。

    2. 静态成员变量必须在类外初始化,初始化时不加static

    3. 类静态成员可用**类名::静态成员** 或 **对象.静态成员**来访问。

    class A
    {
    public:
    	static int GetCount_top()
    	{
    		_top++;
    		return _top;
    	}
    
    	A()
    		:_a1(1)
    	{}
    
    private:
    	int _a1;
    	static int _top;
    };
    
    int A::_top = 0;
    
    int main()
    {
    	A a1;
    	cout << a1.GetCount_top() << endl; // 对象.静态成员
        cout << A().GetCount_top() << endl;
        // A() 为匿名对象
    	cout << A::GetCount_top() << endl; // 类名::静态成员
    
    	return 0;
    }
    
    • 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

    A() 为匿名对象,当前语句结束后自动销毁。

    1. 类静态成员函数没有隐藏的this指针,不能访问任何非静态成员
    2. 静态成员也是类的成员,同样受访问限定符的限制
    int main()
    {
    	A a1;
    	cout << a1._top << endl; // error C2248: “A::_top”: 无法访问 private 成员(在“A”类中声明)
    
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    三、友元

    友元是一种突破封装的方式,部分场景能提供便利。但友元会增加耦合度,不宜多用。

    3.1 友元函数
    class Date
    {
    public:
    	Date(int year = 1900, int month = 1, int day = 1)
    		:_year(year)
    		, _month(month)
    		, _day(day)
    	{}
    
    	friend ostream& operator<<(ostream& out, const Date& d); // 友元函数
    	friend istream& operator>>(istream& in, Date& d);
    
    private:
    	int _year;
    	int _month;
    	int _day;
    };
    
    ostream& operator<<(ostream& out, const Date& d)
    {
    	out << d._year << "-" << d._month << "-" << d._day;
    	return out;
    }
    
    istream& operator>>(istream& in, Date& d)
    {
    	in >> d._year >> d._month >> d._day;
    	return in;
    }
    
    • 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

    友元函数可以直接访问类的私有成员,它是定义在类外部的函数,不是类的成员函数;需要在类的内部声明,声明时加friend

    PS:

    1. 友元函数不能用const修饰

    2. 友元函数可以在类定义的任何位置声明,不受访问限定符限制

    3. 一个函数可以是多个类的友元函数。

    4. 友元函数的调用与普通函数相同。

    3.2 友元类

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

    1. 友元关系是单向的,不具备交换性。
    class A
    {
        friend class B;// B是A的友元类,但A不是B的友元类
    public:
    	A()
    		:_a(1)
        {}
    private:
    	int _a;
    };
    
    class B
    {
    public:
    	B()
    		:_b(1)
    	{
    		A a1;
    	}
    private:
    	int _b;
    };
    
    int main()
    {
    	B b1;
    	return 0;
    }
    
    • 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
    1. 友元关系不能传递

    B是A的友元,C是B的友元,但C和A没有友元关系。

    四、内部类

    4.1 概念

    存在类A、B,如果B定义在A的内部,B称为A的内部类

    内部类是一个独立的类,不属于外部类不能通过外部类的对象访问内部类的成员

    PS: 内部类就是外部类的友元类,外部类不是内部类的友元。

    4.2 特性
    1. 内部类可以定义在外部类的任何位置。
    2. 内部类可以直接访问外部类static成员,不需要使用外部类的 类名对象
    3. sizeof(外部类)=外部类,与内部类无关
  • 相关阅读:
    RocketMQ 发送顺序消息
    [Numpy] np.where
    【实验记录】地磁论文
    Windows下CMD操作常用指令详解
    血液代谢组学炎症相关的线粒体功能失调慢加急性肝衰竭的潜在机制
    前端学习笔记——第三天
    【视频】机器学习交叉验证CV原理及R语言主成分PCA回归分析犯罪率|数据共享
    软件测试 -- 进阶 5 软件测试用例
    hadoop 报不是内部或外部命令的解决办法
    黑马点评--达人探店
  • 原文地址:https://blog.csdn.net/taduanlangan/article/details/134493023