当前位置: 首页 > news >正文

[C++]友元函数和友元类

1. 友元函数

1.1 友元函数的概念

友元函数是一个非成员函数,它被类声明为“友元”,从而能够访问类的私有成员和保护成员。正常情况下,类的外部函数是不能访问类的私有成员的,而友元函数打破了这一限制。

class MyClass {
private:int x;
public:MyClass() : x(10) {}friend void showX(MyClass obj); // 友元函数声明
};// 友元函数定义
void showX(MyClass obj) {cout << "The value of x: " << obj.x << endl; // 访问私有成员
}

1.2 大白话解释为什么

类的私有成员本来是为了保护数据不被外部随意访问,确保类的封装性。然而,有时我们确实需要让外部的非成员函数访问类的私有数据(例如做一些特定操作或性能优化)。这时,我们通过friend关键字声明友元函数,让它“破例”访问类的私有成员,但这种访问是有限制的——友元函数不属于类,不能直接访问类的其他成员。

1.3 实际使用

1.3.1示例:友元函数访问私有数据

#include <iostream>
using namespace std;class Box {
private:int width;
public:Box(int w) : width(w) {} // 构造函数// 友元函数声明friend void printWidth(Box box);
};// 友元函数定义
void printWidth(Box box) {cout << "Box width: " << box.width << endl; // 直接访问私有成员
}int main() {Box box(10);printWidth(box); // 通过友元函数访问私有成员return 0;
}

1.3.2代码解释:

  • Box类中有一个私有成员width,普通的成员函数不能直接访问它。
  • 通过friend关键字,printWidth函数成为了Box类的友元函数,它可以访问Box类的私有成员width
  • 这段代码的执行结果会输出Box width: 10,显示width的值。

1.3.3注意事项:

  • 友元函数并不属于类,类外的普通函数通过friend关键字可以访问类的私有数据,但它并不能访问类的成员函数或其他私有成员。
  • 友元函数的访问权限仅限于类的私有和保护成员。
  • 友元函数在类内声明,在类外定义。

2. 友元类

2.1 友元类的概念

友元类是指一个类允许另一个类访问它的私有成员。通过friend关键字,我们可以让一个类成为另一个类的友元类,从而让这个类的所有成员函数访问另一个类的私有成员。

class Car; // 提前声明类class Engine {
public:void showCarSpeed(Car& car); // 成员函数,访问Car的私有数据
};class Car {
private:int speed;
public:Car(int s) : speed(s) {} // 构造函数// 声明Engine为友元类friend class Engine; // Engine是Car的友元类
};// Engine类的成员函数可以访问Car的私有成员
void Engine::showCarSpeed(Car& car) {cout << "Car speed: " << car.speed << endl; // 直接访问Car的私有成员
}int main() {Car car(100);Engine engine;engine.showCarSpeed(car); // Engine通过友元关系访问Car的私有成员return 0;
}

2.2 大白话解释为什么

有时候两个类之间的功能紧密相关,需要彼此直接访问对方的私有数据。直接暴露所有的私有成员可能破坏封装性,但通过友元类,可以让一个类“授权”另一个类访问它的私有成员,而不暴露给外界。这让两个类能够协同工作,同时又不破坏类的封装性。

2.3 实际使用

2.3.1示例:友元类之间的合作

#include <iostream>
using namespace std;class Engine; // 提前声明class Car {
private:int speed;
public:Car(int s) : speed(s) {}// 声明Engine类为友元类friend class Engine; // Engine可以访问Car的私有成员
};class Engine {
public:void showCarSpeed(Car car) {cout << "Car speed: " << car.speed << endl; // 访问Car类的私有成员}
};int main() {Car car(120);Engine engine;engine.showCarSpeed(car); // Engine访问Car的私有成员return 0;
}

2.3.1代码解释:

  • Car类包含一个私有成员speed,我们希望Engine类能够访问它。
  • 通过friend class Engine;,我们让Engine类成为Car类的友元类,因此Engine类的成员函数能够直接访问Car的私有成员speed
  • main函数中,创建了一个Car对象,并通过Engine类访问其私有成员。

2.3.3注意事项:

  • 友元类能够访问被声明为友元的类的所有私有成员。
  • 友元类不是继承关系,它只是被授权访问类的私有数据,因此它不具有类之间的继承功能。
  • 如果多个类需要访问彼此的私有成员,可以将它们互相声明为友元类。
  • 友元类也是在类内声明,在类外定义。

3. 总结

3.1 友元函数总结

  • 友元函数是非成员函数,但被允许访问类的私有成员。
  • 通过friend关键字声明友元函数,它可以访问类的私有数据。
  • 友元函数并不是类的成员,它只能访问类的私有和保护成员,而不能访问类的其他成员函数或成员变量。
  • 友元函数的访问权限仅限于该类的私有和保护成员。

3.2 友元类总结

  • 友元类是允许访问另一个类私有成员的类。
  • 通过friend class关键字声明友元类,使得友元类的成员函数能够访问被声明类的私有数据。
  • 友元类和继承关系不同,它只是授权给一个类访问另一个类的私有成员,不会影响类的继承关系。
  • 友元类是双向授权的,即一个类可以将另一个类声明为友元类,反之亦然。

http://www.mrgr.cn/news/79427.html

相关文章:

  • 数据类型转换在自然语言处理中的应用
  • RTMP推流平台EasyDSS在无人机推流直播安防监控中的创新应用
  • 麒麟信安推出支持信创PC的新一代云桌面方案,助力政务信创高效安全运维
  • c#动态更新替换json节点
  • 【C++算法】39.模拟_提莫攻击
  • 无网络情况下打包虚拟环境
  • ACM:均分纸牌
  • 人脸识别Adaface之libpytorch部署
  • 红日靶场vulnstark 4靶机的测试报告[细节](二)
  • golang实现简单的redis服务
  • [C++]构造函数和析构函数
  • 第1章:CSS简介 --[CSS零基础入门]
  • nginx代理rabbitmq和配置 Nginx 代理达梦数据库
  • ubuntu下Qt5自动编译配置QtMqtt环境(10)
  • D91【python 接口自动化学习】- pytest基础用法
  • 残差网络连接,使得输入与输出的尺寸一样
  • 十九(GIT2)、token、黑马就业数据平台(页面访问控制(token)、首页统计数据、登录状态失效)、axios请求及响应拦截器、Git远程仓库
  • 海选女主角
  • Day7 苍穹外卖项目 缓存菜品、SpringCache框架、缓存套餐、添加购物车、查看购物车、清空购物车
  • TTC模型(1D和2D)理论推导及python实现
  • 不同系统查看软件占用端口的方式
  • MySQL-DDL之数据库操作
  • vue异步更新,$nextTick
  • 嵌入式系统与移动设备开发
  • SQL:从某行开始,查询一定行数的语句
  • (长期更新)《零基础入门 ArcGIS(ArcMap) 》实验三----学校选址与路径规划(超超超详细!!!)