IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 【温故而知新-01】C++友元小记 -> 正文阅读

[C++知识库]【温故而知新-01】C++友元小记

一、开篇

友元的描述的对象是类和函数,函数可以是类的成员函数和非成员函数。当我们需要访问一个类的非公有成员时(private、protected),这时候友元就可以派上用场啦。

二、友元知识点

在实际使用中,友元可以是:函数和类。我们只需要使用friend关键字在类中对他们进行声明即可。

友元声明只能出现在类定义的内部,可以在类定义中的任意位置进行友元声明。但是,在实际使用中,最好在类定义的开始或者结尾处集中进行友元的声明,这样比较规范!!!

友元的声明仅仅指定了访问的权限,但是本质上不是一个函数声明,所以,如果我们需要使类的用户(类示例、派生类)能够调用某个友元函数,那么就需要在友元声明之外再对在这里插入代码片该函数进行一次声明。在实际使用中,通常把友元的声明和类本身放置在同一个头文件中

注意:许多编译器并没有强制限定友元函数必须在使用之前在类的外部进行声明。但是,在类的外部进行函数声明是一种比较保险的作用。

友元不是类的成员,所以,他不受所在区域访问控制级别的约束(public、private、protected对他无效)

三、友元的三种使用场景

友元存在三种使用场景:友元类友元成员函数友元非成员函数

(3-1)友元类

这这样一个场景:两个学生student_A和student_B,其中student_B是student_A的好朋友,所以希望能够访问student_A的私有数据,所以在设计中在student_A的类定义中将student_A声明为其友元类,这样则可以在student_B中访问student_A的私有数据成员。参考代码如下:

#include <iostream>

class student_B;
/**
 * @brief student_A
 */
class student_A{
    friend student_B;

private:
    int m_age = 25;
    std::string m_name = "xiaoZhang";

    std::string getStudentAName()
    {
        return m_name;
    }

    int getStudentAAge()
    {
        return m_age;
    }

};


/**
 * @brief student_B
 */
class student_B{
public:
    int getStudentInfo(student_A &stu)
    {
        std::cout<<"stu_A name:"<<stu.m_name<<"\r\n"<<"stu_A age : "<<stu.m_age<<std::endl;
    }

private:
    int m_age = 22;
    std::string m_name = "xiaoLi";
};


int main() {
    student_B stu_b;

    student_A stu_a;

    //通过studentB 访问studentA的私有数据成员
    stu_b.getStudentInfo(stu_a);

    return 0;
}

每个类负责控制自己的友元类和友元函数。友元关系不具有传递性。

(3-2)友元成员函数

可以在类中只把一个类的成员函数声明为友元函数。例如:有两个学生Student_A和Student_B,将Student_B的获取学生信息getInfo()声明为Student_A学生的友元函数,那么Student_B的getInfo()则可以访问Student_A学生的私有数据成员。参考代码如下:

#include <iostream>

/* 声明student_A */
class student_A;
int getStudentInfo(student_A &stu);

/* 定义student_B类 */
/**
 * @brief student_B
 */
class student_B{
public:
    /* 在student_B中先声明getStudentInfo()函数,但是不定义他 */
    int getStudentInfo(student_A &stu);

private:
    int m_age = 22;
    std::string m_name = "xiaoLi";
};

/* 定义student_A类 */
/**
 * @brief student_A
 */
class student_A{
    /* 声明student_B类的getStudentInfo()函数为student_A类的友元 */
    friend int student_B::getStudentInfo(student_A &stu);

private:
    int m_age = 25;
    std::string m_name = "xiaoZhang";

    std::string getStudentAName()
    {
        return m_name;
    }

    int getStudentAAge()
    {
        return m_age;
    }
};

/* 定义student_B类的getStudentInfo()成员函数 */
int student_B::getStudentInfo(student_A &stu) {
    std::cout<<"stu_A name:"<<stu.m_name<<"\r\n"<<"stu_A age : "<<stu.m_age<<std::endl;

    return 0;
}


int main() {
    student_B stu_b;

    student_A stu_a;

    /* 通过studentB 访问studentA的私有数据成员 */
    stu_b.getStudentInfo(stu_a);

    return 0;
}

在友元的三种使用方法中,将类的成员函数作为某一个类的友元函数,在程序的结构编写上需要格外注意代码的顺序,否则将会非常容易出错。以以上代码为例,必须按照如下的方式对代码进行结构上的处理:

  • 首先定义student_B类,其中声明getStudentInfo()函数,但是不能定义该函数。除此之外,还需要在student_B类定义之前先声明student_A类,因为在getStudentInfo()中使用到了student_A。

  • 接着,定义student_A类,在该类定义中先对student_B类的getStudentInfo()进行友元声明。

  • 最后定义getStudentInfo()函数,这样才能在该函数中使用student_A的私有成员。

(3-3)友元非成员函数

可以在类中把一个非成员函数声明为友元函数,那么该函数可以访问该类中的私有成员。例如下列代码:

#include <iostream>

/**
 * @brief student_A
 */
class student_A{
    //声明getStudentInfo()这个非成员函数作为student_A类的友元函数
    friend int getStudentInfo();

private:
    int age = 25;
    std::string name = "xiaoZhang";
    
    std::string getStudentAName()
    {
        return name;
    }
};

/**
 * @brief getStudentInfo
 * @brief 打印出学生的名字和年龄
 */
int getStudentInfo()
{
    //创建student_A的一个实例
    student_A a;
    
    //访问student_A的私有成员(私有属性、私有成员函数)
    std::cout<<"student name:"<<a.getStudentAName()<<std::endl;
    std::cout<<"student age:"<<a.age<<std::endl;

    return -1;
}


int main() {
    getStudentInfo();
    return 0;
}
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-07-05 23:22:06  更:2022-07-05 23:24:06 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 16:30:59-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码