C++:友元函数与友元类

概念

  1. 在类的内部使用friend 关键字取修饰 类/函数的声明,使得这个函数/类 成为 该类的友元函数/友元类
  2. 友元函数/友元类的声明可以在任意的位置进行,不论是在 public 、private、protected区域下,效果都是一样的,都是获取类的成员变量的权限!
  3. 友元函数/友元类具有访问类内部成员变量的权限,但并不是类的成员
  4. 友元函数在声明时需要使用friend修饰,但是在定义时不需要
  5. 友元函数/友元类是单向的,例如A类中有一个友元类B,B类的成员函数可以使用A类的成员变量,但是A类的成员变量不能使用B类的成员函数
  6. 友元函数不具有传递性,例如A类的内部有友元类B,B类内部有友元类C,类B可以用类A的成员变量,类C可以用类B的成员变量,但是类C不能用类A的成员变量。

友元函数的实现方式

1、友元函数是普通的全局函数

cpp 复制代码
#include <iostream>

using namespace std;

class A
{

 private:
     int A;
  public:
     print(){};
     
     //声明全局函数 person 是 类A 的友元函数
     friend void person (int &x);
}


void person(int &x)
{
   //使用了类A的成员变量age
   cout << "age=" << p.age << endl;
  
}

int main ()
{
   A p(22);
   person(p);
   return 0;
}

2、友元函数是其他类的成员函数

cpp 复制代码
#include <iostream>

using namespace std;

class A
{

 private:
     int A;
  public:
     print(){};
     
     //声明类B的成员函数 person 是 类A 的友元函数
     friend  void B::person (int &x);
}


class B
{
  private:
     int B;
  public:
     person(int &x);

}

B::person(int &x)
{
   //因为类B的成员函数person是类A的友元函数,所以看可以使用类A的成员变量age
   cout << "age=" << p.age << endl;
  
}

int main ()
{
   A p(22);

   B q;
   q.person(p);
   return 0;
  
}

友元类

cpp 复制代码
//时间类
class Time
{
   friend class Date;   
// 声明日期类为时间类的友元类,则在日期类中就直接访问Time类中的私有成员变量

public:

 //成员函数的初始化列表
 Time(int hour = 0, int minute = 0, int second = 0)
 : _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;
};

优缺点总结

缺点:友元函数不是类的成员但是却具有成员的权限,可以访问类中受保护的成员,这破坏了类的封装特性和权限管控;

优点:可以实现类之间的数据共享;比如上面互为友元类,则可以互相访问对方受保护的成员;

总结:友元函数是一种破坏封装特性的机制,可以让程序员写代码更灵活,但是不能滥用;

相关推荐
小白学大数据4 分钟前
拼多多反爬对抗实战:Scrapy 中间件化采集架构解析
开发语言·scrapy·中间件·架构
colinu12 分钟前
C++ 异步任务与线程生命周期:`std::async`、`future`、`thread`、`jthread` 与协作式退出
java·jvm·c++
学逆向的32 分钟前
win32注入代码
开发语言·网络安全·api·win32
wuminyu1 小时前
ForkJoinPool窃取线程在扫描其他WorkQueue时的随机采样算法与Phase线程挂起唤醒机制解析
java·linux·c语言·jvm·c++
longlongzihan1 小时前
链表找环:Floyd 判圈算法(LeetCode 141 & 142 )
c++·算法·leetcode·链表
Sarvartha1 小时前
内部类知识
java·开发语言
liulilittle1 小时前
Linux 下 select 测试函数
linux·服务器·网络·数据库·c++·select·c
FPGA小徐2 小时前
【一生一芯 / PA】异常响应机制:RISC-V 中 ecall → mtvec → mret 的完整代
开发语言·数据库·c#
北京盛世宏博2 小时前
工业环境监测选型:Modbus TCP以太网温湿度传感器部署、调试、避坑全指南
开发语言·网络·php
无忧.芙桃2 小时前
C++语言原理与实践(十二):list类的底层实现
c++·windows·list