当前位置: 代码网 > it编程>编程语言>C/C++ > C++友元函数和友元类的使用详解

C++友元函数和友元类的使用详解

2025年10月14日 C/C++ 我要评论
1、友元函数是什么?首先,得有个比较总体的认识,我个人认为友元函数是一个补丁。在c++中,一个类中可以有 public、protected、private 三种属性的成员,通过对象可以访问 publi

1、友元函数是什么?

首先,得有个比较总体的认识,我个人认为友元函数是一个补丁。

在 c++ 中,一个类中可以有 public、protected、private 三种属性的成员,通过对象可以访问 public 成员,只有本类中的函数可以访问本类的 private 成员。

但是c++中依旧保留了,独立的函数,也就是不依赖某个class存在(你可以理解为c中的函数),如果此时我们函数需要调用某一个class中定义的变量,这时就无法实现这个功能。所以友元函数或友元类就出现了,专门来打这个补丁。

小结:友元函数即针对访问某一个class中的成员变量和成员函数。

2、友元函数的关键字friend

其中友元函数按照定义或声明的位置来区分,可以分为两种:

(1):class外定义的函数

(2):其他类中定义的成员函数

2.1、class外定义的函数在某个class中说明为这个类的友元函数

标题看起来有点拗口,但是却很好的解释了,这个友元函数定义和声明的状态?

闲话少说,直接看代码

#include <iostream>
using namespace std;
class student{
public:
    student(char *name, int age, float score); //构造函数
public:
    friend void show(student *pstu);  //将show()声明为类student的友元函数
private:
    char *m_name;
    int m_age;
    float m_score;
};
student::student(char *name, int age, float score): m_name(name), m_age(age), m_score(score){ }
//非成员函数
void show(student *pstu){
    cout<<pstu->m_name<<"的年龄是 "<<pstu->m_age<<",成绩是 "<<pstu->m_score<<endl;
}
int main(){
    student stu("小明", 15, 90.6);
    show(&stu);  //调用友元函数
    student *pstu = new student("李磊", 16, 80.5);
    show(pstu);  //调用友元函数
    return 0;
}

友元函数的声明:

shennd void show(student *pstu);  //将show()声明为类student的友元函数

友元函数的定义:

void show(student *pstu){
    cout<<pstu->m_name<<"的年龄是 "<<pstu->m_age<<",成绩是 "<<pstu->m_score<<endl;
}

注意看,我标红的地方,即友元函数的形参,是class类型的指针。具体函数的代码中,使用指针和->来调用类中的成员函数或成员变量。

除了上面说的,还有几点需要额外说明

*1)、友元函数,可以声明在任何位置,public,private,protect,而且都不会影响

*2)、如果函数不声明为友元函数,但是形参是class类型的指针,则也可以访问其public成员或函数。

友元函数的调用:

  • 我们在主函数中调用,注意此时的形参,先声明一个实例,然后取这个实1例的地址作为实参,这是因为成员函数在调用时会隐式地增加 this 指针,指向调用它的对象,从而使用该对象的成员;
  • 而 show() 是非成员函数,没有 this 指针,编译器不知道使用哪个对象的成员,要想明确这一点,就必须通过参数传递对象(可以直接传递对象,也可以传递对象指针或对象引用),并在访问成员时指明对象。

2.2、将其他类的成员函数声明为友元函数

friend 函数不仅可以是全局函数(非成员函数),还可以是另外一个类的成员函数。请看下面的例子:

#include <iostream>
using namespace std;
class address;  //提前声明address类
//声明student类
class student{
public:
    student(char *name, int age, float score);
public:
    void show(address *addr);
private:
    char *m_name;
    int m_age;
    float m_score;
};
//声明address类
class address{
private:
    char *m_province;  //省份
    char *m_city;  //城市
    char *m_district;  //区(市区)
public:
    address(char *province, char *city, char *district);
    //将student类中的成员函数show()声明为友元函数
    friend void student::show(address *addr);
};
//实现student类
student::student(char *name, int age, float score): m_name(name), m_age(age), m_score(score){ }
void student::show(address *addr){
    cout<<m_name<<"的年龄是 "<<m_age<<",成绩是 "<<m_score<<endl;
    cout<<"家庭住址:"<<addr->m_province<<"省"<<addr->m_city<<"市"<<addr->m_district<<"区"<<endl;
}
//实现address类
address::address(char *province, char *city, char *district){
    m_province = province;
    m_city = city;
    m_district = district;
}
int main(){
    student stu("小明", 16, 95.5f);
    address addr("陕西", "西安", "雁塔");
    stu.show(&addr);
   
    student *pstu = new student("李磊", 16, 80.5);
    address *paddr = new address("河北", "衡水", "桃城");
    pstu -> show(paddr);
    return 0;
}
friend void student::show(address *addr);

这是在address中声明student中的show()函数为,address的友元函数

3、友元类

不仅可以将一个函数声明为一个类的“朋友”,还可以将整个类声明为另一个类的“朋友”,这就是友元类。

友元类中的所有成员函数都是另外一个类的友元函数。

class address{
public:
address(char *province, char *city, char *district);
public:
//将student类声明为address类的友元类
friend class student;
private:
char *m_province; //省份
char *m_city; //城市
char *m_district; //区(市区)
};

注意第6行中,定义一个友元类,结构上简单的多,就是在此class中,+一个声明语句即可“friend class student;

关于友元,有两点需要说明:

  • 友元的关系是单向的而不是双向的。如果声明了类 b 是类 a 的友元类,不等于类 a 是类 b 的友元类,类 a 中的成员函数不能访问类 b 中的 private 成员。
  • 友元的关系不能传递。如果类 b 是类 a 的友元类,类 c 是类 b 的友元类,不等于类 c 是类 a 的友元类。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

  • 深入解析C++中的智能指针

    一、raii和智能指针raii是resource acquisition is initialization的缩写,它的意思是获取资源立即初始化。本质是⼀种利用对象生命周期来管理获…

    2025年10月19日 编程语言
  • C++构建缓存加速的实现示例

    C++构建缓存加速的实现示例

    1、非修改序列算法这些算法不会改变它们所操作的容器中的元素。1.1 find 和 find_iffind(begin, end, value):查找第一个等于v... [阅读全文]
  • 详解C++中代理模式高级应用

    详解C++中代理模式高级应用

    1、非修改序列算法这些算法不会改变它们所操作的容器中的元素。1.1 find 和 find_iffind(begin, end, value):查找第一个等于v... [阅读全文]
  • c++中类的对象初始化的实现示例

    c++中类的对象初始化的实现示例

    在 c++ 中,类的对象初始化是创建对象时为其成员变量赋予初始值的过程,核心依赖构造函数(类的特殊成员函数)。根据场景和需求,对象初始化有多种方式,下面详细介绍... [阅读全文]
  • 详解C++类型兼容性规则

    详解C++类型兼容性规则

    一个公有派生类的对象在使用上可以被当作基类的对象,反之则禁止。具体表现在:派生类的对象可以被赋值给基类对象。 派生类的对象可以初始化基类的引用。 指向基类的指针... [阅读全文]
  • C++中stack和queue的用法及说明

    前言在 c++ 中,stack(栈)和 queue(队列)是两种常用的容器适配器,分别用于管理数据的后进先出(lifo)和先进先出(fifo)访问模式。本文将详细介绍这两种数据结构…

    2025年10月10日 编程语言

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com