C++ 友元 / friend关键字解读

[复制链接]
发表于 2025-10-12 22:12:38 | 显示全部楼层 |阅读模式
1.1. C++面向生存 

借助一个生存中的例子来明白友元技能: 
在生存中,你的家里有 客堂(Public)寝室(Private)

  • 客堂 是开放的,任何来访的客人都可以进入。
  • 寝室 是私密的,只有你自己能进去。
  • 但是,你可以允许你的好朋侪进入你的寝室,他们不会像平凡客人那样被拒之门外。
在 C++ 里,类的 私有(private)公共(public) 访问权限就雷同这种关系。
假如想让类外的特定函数或类访问私有成员,就须要用到“友元(friend)”技能。
友元的作用是 让某些特别的函数或类访问另一个类的私有成员,就像你允许好朋侪进入你的寝室一样。
C++ 中的 友元(friend) 关键字提供了三种实现方式:

  • 全局函数做友元(允许某个函数访问私有成员)
  • 类做友元(允许某个类的全部成员函数访问私有成员)
  • 成员函数做友元(只允许某个特定的成员函数访问私有成员)
通过友元机制,我们可以在 保持封装性的同时,机动地控制访问权限,让特定的外部函数或类可以大概访问私有数据。
1.2. 全局函数做友元
  1. friend void goodGay(Building &building); // goodGay全局函数是 Building好朋友,可以访问Building中私有成员
复制代码
团体代码: 
  1. #include<iostream>#include<string>typedef std::string STRING; // 为 std::string 界说一个新的范例别名 STRING。                            // 等价于:using STRING = std::string;(C++11引入)class Building{    private:    STRING m_BedRoom; // 寝室    public:    STRING m_SittingRoom; // 客堂    // 构造函数    Building(){        m_SittingRoom="客堂";        m_BedRoom="寝室";    }   
  2. friend void goodGay(Building &building); // goodGay全局函数是 Building好朋友,可以访问Building中私有成员
  3. };// 全局函数void goodGay(Building &building){    std::cout<<"好基友全局函数正在访问:"<<building.m_SittingRoom<<std::endl;    std::cout<<"好基友全局函数正在访问:"<<building.m_BedRoom<<std::endl;}int main(){    Building house1; // 实例化一个house1    goodGay(house1);    return 0;}// 输出:// 好基友全局函数正在访问:客堂// 好基友全局函数正在访问:寝室
复制代码
1.3. 类做友元
  1. friend class GoodGay; // GoodGay类是本类的好朋友,可以访问本类中私有成员
复制代码
  1. #include<iostream>#include<string>typedef std::string STRING; // 为 std::string 界说一个新的范例别名 STRING。                            // 等价于:using STRING = std::string;(C++11引入)class Building{    private:    STRING m_BedRoom; // 寝室    public:    STRING m_SittingRoom; // 客堂    // 构造函数    Building(){        m_SittingRoom="客堂";        m_BedRoom="寝室";    }   
  2. friend class GoodGay; // GoodGay类是本类的好朋友,可以访问本类中私有成员};class GoodGay{    public:    void visit(Building &building){ // 观光函数  访问Building中的属性        std::cout<<"好基友类正在访问:"<<building.m_SittingRoom<<std::endl;        std::cout<<"好基友类正在访问:"<<building.m_BedRoom<<std::endl;    }    };int main(){    Building house1; // 实例化一个house1    GoodGay gg1; // 实例化一个好基友    gg1.visit(house1); // 好基友1访问house1中的属性【客堂、寝室】    return 0;}// 输出:// 好基友类正在访问:客堂// 好基友类正在访问:寝室
复制代码
1.4. 成员函数做友元

成员函数做友元时,我们可以只让某个特定的成员函数访问类的私有成员,而不是整个类。
语法: 
  1. // 只让 GoodGay 类的 visit 函数访问私有成员
  2.     friend void GoodGay::visit(Building &building);
复制代码
详细看下面的代码: 
错误示例:
  1. #include<iostream>#include<string>typedef std::string STRING; // 为 std::string 界说一个新的范例别名 STRING。                            // 等价于:using STRING = std::string;(C++11引入)class GoodGay; // 提前声明 GoodGay 类class Building{    private:    STRING m_BedRoom; // 寝室    public:     STRING m_SittingRoom; // 客堂    // 构造函数    Building(){        m_SittingRoom="客堂";        m_BedRoom="寝室";    }   
  2. // 只让 GoodGay 类的 visit 函数访问私有成员
  3.     friend void GoodGay::visit(Building &building);};class GoodGay{    public:    void visit(Building &building){ // 观光函数  访问Building中的属性        std::cout<<"好基友类正在访问:"<<building.m_SittingRoom<<std::endl;        std::cout<<"好基友类正在访问:"<<building.m_BedRoom<<std::endl;    }   };int main(){    Building house1; // 实例化一个house1    GoodGay gg1; // 实例化一个好基友    gg1.visit(house1); // 好基友1访问house1中的属性【客堂、寝室】    return 0;}
复制代码
 错误点:

缘故起因: friend 关键字的使用位置不精确
标题分析

  •         GoodGay 类的界说在 Building 之后


  • 但是在 Building 里写 friend void GoodGay::visit(Building &building);,编译器此时还 不知道 GoodGay 类里有 visit 这个成员函数。

  •         办理方案


  • 须要先 完备界说 GoodGay 类,然后 Building 再声明 GoodGay::visit 为友元。
 精确示例:
  1. #include <iostream>#include <string>typedef std::string STRING; // 界说字符串范例别名class Building; // 先声明 Building 类class GoodGay {public:    void visit(Building &building); // 只有 visit 这个函数是友元};class Building {private:    STRING m_BedRoom; // 寝室(私有成员)public:    STRING m_SittingRoom; // 客堂(公有成员)    // 构造函数    Building() {        m_SittingRoom = "客堂";        m_BedRoom = "寝室";    }   
  2. // 只让 GoodGay 类的 visit 函数访问私有成员
  3.     friend void GoodGay::visit(Building &building);};// **界说 visit 函数**void GoodGay::visit(Building &building) {     std::cout << "好基友访问: " << building.m_SittingRoom << std::endl;    std::cout << "好基友访问: " << building.m_BedRoom << std::endl; // 允许访问私有成员}int main() {    Building house1; // 实例化一个 Building 对象    GoodGay gg1; // 实例化一个 GoodGay 对象    gg1.visit(house1); // 访问 house1 的成员变量【客堂、寝室】    return 0;}
复制代码
输出: 
  1. 好基友类正在访问: 客厅
  2. 好基友类正在访问: 卧室
复制代码

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表