首页 > 基础资料 博客日记
【C++】友元类 ( 友元类简介 | 友元类声明 | 友元类单向性 | 友元类继承性 | 友元类作用 | 友元类和友元函数由来 | Java 反射机制 | C / C++ 编译过程 )
2024-05-25 12:00:06基础资料围观197次
文章目录
一、友元类简介
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;
}
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;
在 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;
}
执行结果 :
执行 Student 的构造函数
age + height = 2
执行 Student 的构造函数
执行 Student 的析构函数
age + height = 130
请按任意键继续. . .
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:jacktools123@163.com进行投诉反馈,一经查实,立即删除!
标签: