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;
};

优缺点总结

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

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

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

相关推荐
蒸蒸yyyyzwd2 小时前
与Redis和MySQL有关的知识
c++·求职招聘·八股
CodeStats2 小时前
【Java数据类型】Java底层数据类型原理(下):时间API、JSON与String存储演进
java·开发语言·数据类型·string·byte
欧特克_Glodon2 小时前
OpenCV计算机视觉开发入门与实践<四十>:自动识别物体数量
c++·人工智能·opencv·计算机视觉
Brilliantwxx2 小时前
【STM32 】把 printf 搬到串口上 —— C 标准 IO 函数重定向与多文件工程搭建(实战串口电灯)
c语言·开发语言·stm32·单片机·嵌入式硬件·架构·ecmascript
wuminyu2 小时前
Kafka利用sendfile与Page Cache实现高性能传输剖析
java·linux·c语言·jvm·c++
hansang_IR2 小时前
【题解】P4456 [CQOI2018] 交错序列(数学递推)
c++·算法
流浪0012 小时前
大厂 C/C++ 2023–2025 面试答案题汇总
开发语言·c++
青少儿编程课堂2 小时前
贪心算法进阶:区间调度与最少资源整合解析
c++·python·算法·贪心·信息学竞赛·区间调度
Yanjun2i2 小时前
Agent学习记录六:Tool 类 + Tool Registry
开发语言·python·学习
一条泥憨鱼2 小时前
【从0开始学习计算机网络】| TIME_WAIT 为什么是 2MSL,CLOSE_WAIT / TIME_WAIT 堆积怎么排查
服务器·开发语言·网络·计算机网络·网络安全