13.友元成员函数

13.面向对象-封装-友元成员函数


13.1 知识点

友元成员函数的概念

  • 友元成员函数是一个类的成员函数,但被另一个类声明为 friend
  • 该函数可以访问另一个类的私有 (private) 和保护成员 (protected)
  • 我们在友元函数的练习题二中已经使用过友元成员函数了

友元成员函数的使用

#pragma once
#include "Lesson13B.h"

class Lesson13A
{
private:
    int i = 10;
    float f = 5.5f;
    void test() const
    {

    }

    // 声明 Lesson13B 的 showLesson13AInfo 函数是 Lesson13A 的友元成员函数
    friend void Lesson13B::showLesson13AInfo(const Lesson13A& a);
};
#pragma once

class Lesson13A;

class Lesson13B
{
public:
    void showLesson13AInfo(const Lesson13A& a);
};
#include "Lesson13B.h"
#include "Lesson13A.h"
#include <iostream>
using namespace std;

void Lesson13B::showLesson13AInfo(const Lesson13A& a)
{
    cout << a.i << endl;
    cout << a.f << endl;
    a.test();
}

Lesson13A a;
Lesson13B b;
b.showLesson13AInfo(a);
// 10
// 5.5

友元函数和友元成员函数的区别

  • 友元函数不是任何类的成员,相当于是一个全局函数,可以直接使用
  • 友元成员函数是某个类的成员,需要通过类对象点出调用

13.2 知识点代码

Lesson13A.h

#pragma once
#include "Lesson13B.h"

class Lesson13A
{
private:
    int i = 10;
    float f = 5.5f;
    void test() const
    {

    }

    //声明Lesson13B的showLesson13AInfo函数是Lesson13A的友元成员函数
    friend void Lesson13B::showLesson13AInfo(const Lesson13A& a);
};

Lesson13B.h

#pragma once

class Lesson13A;

class Lesson13B
{
public:
    void showLesson13AInfo(const Lesson13A& a);
};

Lesson13B.cpp

#include "Lesson13B.h"
#include "Lesson13A.h"
#include <iostream>
using namespace std;

void Lesson13B::showLesson13AInfo(const Lesson13A& a)
{
    cout << a.i << endl;
    cout << a.f << endl;
    a.test();
}

Lesson13_面向对象_封装_友元成员函数.cpp

#include <iostream>
#include "Lesson13A.h"
#include "Lesson13B.h"

int main()
{
    #pragma region 知识点一 友元成员函数的概念
    //友元成员函数是一个类的成员函数,但被另一个类声明为friend
    //该函数可以访问另一个类的私有(private)和保护成员(protected)

    //我们在友元函数的练习题二中已经使用过友元成员函数了
    #pragma endregion

    #pragma region 知识点二 友元成员函数的使用
    //规则:
    //1.在类中通过
    //	friend 返回类型 类名::函数名(参数);
    //	的方式声明另一个类的成员函数为自己的友元
    //2.在另一个类中声明和定义友元成员函数
    //	该友元成员函数中可以访问对应类的私有(private)和保护成员(protected)
    Lesson13A a;
    Lesson13B b;
    b.showLesson13AInfo(a);
    //10
    //5.5

    #pragma endregion

    #pragma region 知识点三 友元函数和友元成员函数的区别
    //友元函数 不是任何类的成员,相当于是一个全局函数,可以直接使用
    //友元成员函数 是某个类的成员,需要通过类对象点出调用
    #pragma endregion
}

13.3 练习题

请简要说明友元成员函数有什么作用

友元函数是一个非成员函数(通常为全局函数),被授权访问某个类的私有或保护成员。它不属于任何类,但能够访问类的内部数据,并且可以在任何地方使用。

友元类则是将一个类声明为另一个类的友元,授权它的所有成员函数访问被声明类的私有或保护成员,这是一种类与类之间的特殊信任关系。

友元成员函数则是将另一个类中的某个特定成员函数声明为本类的友元,仅精准授权这一成员函数访问本类的私有或保护成员。这种机制在不破坏封装的前提下,为特定函数提供例外访问权限,常见于设计模式、运算符重载和跨类协作等场景。

将友元类中的练习题二修改为通过友元成员函数的方式去实现

Monster 类中,不再使用 friend class MonsterFactory;,而是只授权 MonsterFactory::createMonster 这一成员函数成为友元:

// 原先的友元声明方式:
// friend class MonsterFactory;

// 替换为友元成员函数:
friend Monster MonsterFactory::createMonster();

13.4 练习题代码

Monster.h

#pragma once
#include "MonsterFactory.h"
//怪物类
class Monster
{
private:
    Monster() 
    {

    }

    //friend class MonsterFactory;
    //使用友元成员函数
    friend Monster MonsterFactory::createMonster();
};

MonsterFactory.h

#pragma once
//怪物工厂 专门用来管理游戏中的怪物 
//比如怪物的创建 怪物的移除 怪物的记录
class Monster;
class MonsterFactory
{
    //需要一个容器去管理创建的怪物
public:
    //创建怪物(可以改为 堆上分配)
    Monster createMonster();
    //还会有移除怪物的方法

    //如果怪物都在堆上分配 那么内存管理 又应该通过怪物工厂如何去管理呢
};

MonsterFactory.cpp

#include "MonsterFactory.h"
#include "Monster.h"

Monster MonsterFactory::createMonster()
{
    return Monster();
}

Lesson13_练习题.cpp

#include <iostream>

int main()
{
    #pragma region 练习题一
    //请简要说明友元成员函数有什么作用
    // 
    //友元函数:一个非成员函数(通常会是一个全局函数),被授权访问某个类的私有或保护成员
    //		   不属于任何类,但是它能访问类的内部的数据 ,在任何地方都可以使用 
    //友元类:某个类被授权为友元类后,它的所有的成员函数都可以访问另一个类的私有或保护成员
    //		  类与类之间吗 的一种 特别的信任关系,在类当中可以访问另一个类的私有和保护
    //友元成员函数:将另一个类中的某个成员函数声明为友元,让其可以访问本类中的私有或保护成员
    //		 精准授权给某一个成员函数

    //友元成员函数是一种在 不破坏封装 的前提下 ,授权信任对象进行 例外访问 的机制
    //比如 设计模式、运算符重载、跨类协作等场景 会经常使用 
    #pragma endregion

    #pragma region 练习题二
    //将友元类中的练习题二,修改为通过友元成员函数的方式去实现
    #pragma endregion
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏