• 【C++】友元类 ( 友元类简介 | 友元类声明 | 友元类单向性 | 友元类继承性 | 友元类作用 | 友元类和友元函数由来 | Java 反射机制 | C / C++ 编译过程 )






    一、友元类简介




    1、友元类引入


    在 C++ 语言中 , " 友元类 " 是 一个类 与 另外一个类 的 特殊类关系累 ,

    类 A 的 " 友元类 " B 中 , 可以直接访问 A 类 的 私有成员 和 受保护成员 ;

    • B 是 A 的好朋友 , B 可以访问 A 的所有成员 ;

    2、友元类声明


    声明一个 类 B 是 另一个类 A 的 友元类 , 可以 在类 A 中使用 friend 关键字来声明 ;

    • B 是 A 的 友元类 ;
    • B 类中定义 A 类型成员变量 ;
    • B 可以访问 A 中的 所有成员 , 包括 私有成员 或 受保护成员 ;
    • B 可以看做 A 的 数据操作辅助类 ;

    代码示例 :

    class Student
    {
    private:
    	// 声明 StudentCaculate 类是 Student 类的友元类
    	// 在 StudentCaculate 类中可以访问 Student 类中的私有成员
    	friend class StudentCaculate;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    3、友元类单向性


    友元类单向性 :

    友元类关系是单向的 , 声明一个类 B 是 另一个类 A 的 友元类 ,

    B 可以访问 A 的 所有成员 ,

    但是 A 不是 B 的友元类 , A 不能访问 B 的私有和保护成员 ;


    4、友元类继承性


    友元类 关系不具有继承性 , 即 子类不能直接继承父类的友元类 ;


    5、友元类作用


    友元类主要作用 :

    • 作为 某个类的 数据操作 辅助类 ;
    • 作为 多个类 之间 传递信息 的 辅助类 ;




    二、友元类和友元函数由来




    1、友元类和友元函数引入


    友元类 和 友元函数 会破坏 C++ 面向对象 的封装性 , 那么为什么还会出现该机制呢 ?

    有些编程场景 , 需要破坏类的封装性 , 需要访问类的私有属性 ;

    • Java 中给出的方案是 反射机制 ;
    • C++ 中给出的方案是 友元函数 和 友元类 ;

    2、Java 反射机制


    Java 类编译成 class 字节码后 , 可以通过 反射 字节码 的方式 访问 类的私有属性 ;

    反射机制 在 特定领域开发 中应用广泛 , 如 SDK , 开发框架 , 逆向 等领域中 ;

    反射机制 是 面向切面编程 AOP 的基础 ;

    反射机制 成为一种编程标准 ;


    3、C / C++ 编译过程


    C 代码 和 C++ 代码 , 编译成 so 动态库 或 a 静态库 , 需要如下步骤 :

    • 预编译
    • 编译
    • 汇编
    • 链接

    在这里插入图片描述

    最终的 函数库 中 都是汇编指令 , 机器码指令 , 如果要从指令中查找指定的类的私有属性 , 该操作难度很大 ;






    三、友元类代码示例



    在 Student 类中 , 定义了友元类 StudentCaculate ,

    	// 声明 StudentCaculate 类是 Student 类的友元类
    	// 在 StudentCaculate 类中可以访问 Student 类中的私有成员
    	friend class StudentCaculate;
    
    • 1
    • 2
    • 3

    在 StudentCaculate 中 , 定义了 Student 类型成员变量 , 可以访问 Student 对象的所有成员 , 包括 私有成员 和 保护成员 ;


    代码示例 :

    #include "iostream"
    using namespace std;
    
    class Student
    {
    public:
    	// 带参构造函数
    	Student(int age = 1, int height = 1)
    	{
    		this->age = age;
    		this->height = height;
    		cout << "执行 Student 的构造函数" << endl;
    	}
    
    	~Student()
    	{
    		cout << "执行 Student 的析构函数" << endl;
    	}
    
    public:
    	// 打印类数据
    	void print()
    	{
    		cout << " age = " << age  << " , height = " << height << endl;
    	}
    
    private:
    	// 声明 StudentCaculate 类是 Student 类的友元类
    	// 在 StudentCaculate 类中可以访问 Student 类中的私有成员
    	friend class StudentCaculate;
    
    	// 声明友元函数 
    	friend void changeAge(Student* s, int age);
    
    private:
    	int age;		// 年龄
    	int height;		// 身高
    };
    
    class StudentCaculate
    {
    public:
    	void fun()
    	{
    		cout << "age + height = " << student.age + student.height << endl;
    	};
    public:
    	// 此处会自动调用默认的构造函数
    	// 默认值都为 1
    	Student student;
    };
    
    // 在友元函数中 访问 age 私有属性
    void changeAge(Student* s, int age)
    {
    	s->age = age;
    }
    
    
    
    int main() {
    	
    	// 声明 Student 友元类 StudentCaculate 对象
    	StudentCaculate sc;
    
    	// 调用 sc 对象中的 fun , 其中调用了 Student 的私有成员
    	sc.fun();
    
    
    	// 为 StudentCaculate 设置一个非默认值
    	sc.student = Student(10, 120);
    
    	// 调用 sc 对象中的 fun , 其中调用了 Student 的私有成员
    	sc.fun();
    	
    
        // 控制台暂停 , 按任意键继续向后执行
        system("pause");
    
        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
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81

    执行结果 :

    执行 Student 的构造函数
    age + height = 2
    执行 Student 的构造函数
    执行 Student 的析构函数
    age + height = 130
    请按任意键继续. . .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述

  • 相关阅读:
    300. 最长递增子序列
    RJ45水晶头网线顺序出错排查
    2023年11月12日阿里云产品全面故障的启示
    OPENSQL快速学习
    kubernetes 存储流程
    【Hello Go】Go语言函数
    快来直播带你了解中国互联网大厂布局元宇宙现状如何?
    叠加阶梯图和线图及合并线图和针状图
    RabbitMQ-06 持久化
    在智能家居领域产品中常用芯片
  • 原文地址:https://blog.csdn.net/han1202012/article/details/133392310