12.友元类

12.面向对象-封装-友元类


12.1 知识点

友元类的概念

  • 友元类是允许一个类访问另一个类的私有 (private) 和保护 (protected) 成员
  • 友元类的作用类似于友元函数,但是它赋予了整个类访问权限,而不仅限于某个函数

友元类的使用

  • 规则:

      1. 在一个类中利用 friend 关键字让一个类成为该类的友元
      friend class 另一个类类名;
      
      1. 一个类成为了另一个类的友元类后,就可以在其中访问另一个类的私有或保护成员了
  • 注意:

      1. 友元关系不能逆向,除非互为友元
      1. 友元关系不能传递,即父类为一个类的友元,它的子类并不继承这个关系

代码示例:

#pragma once
#include <iostream>
using namespace std;

class Lesson12B;

class Lesson12A
{
public:
    int i2 = 11;
    double d = 45.2;
    void showLesson12BInfo(Lesson12B& b);

private:
    int i = 10;
    float f = 5.5f;
    void testPrivate()
    {
        cout << "私有方法" << endl;
    }

protected:
    bool b = true;
    void testProtected()
    {
        cout << "保护方法" << endl;
    }

    //让另一个类成为我的朋友 这样它就可以访问我内部的私有、保护的成员了
    friend class Lesson12B;
};
#pragma once
class Lesson12A;

class Lesson12B
{
private:
    int ib = 111;
public:
    void showLesson12AInfo(const Lesson12A& a);
    void showLesson12AInfo2(Lesson12A& a);

    //friend class Lesson12A;//需要声明后A才能是B的友元类 只声明B是A的友元类不是双向的
};
#include "Lesson12A.h"
#include "Lesson12B.h"

void Lesson12A::showLesson12BInfo(Lesson12B& b)
{
    //b.ib //报错 友元类只是单向
}
#include "Lesson12B.h"
#include "Lesson12A.h"
#include <iostream>
using namespace std;

void Lesson12B::showLesson12AInfo(const Lesson12A& a)
{
    cout << a.i << endl;
    cout << a.i2 << endl;
    cout << a.d << endl;
    cout << a.f << endl;
    cout << a.b << endl;
    //const对象参数 只能点出const方法 普通方法不能用
}

void Lesson12B::showLesson12AInfo2(Lesson12A& a)
{
    cout << a.i << endl;
    cout << a.i2 << endl;
    cout << a.d << endl;
    cout << a.f << endl;
    cout << a.b << endl;
    a.testPrivate();
    a.testProtected();
}

测试调用代码

Lesson12A a;
Lesson12B b;
b.showLesson12AInfo(a);
b.showLesson12AInfo2(a);

// 输出:
// 10
// 11
// 45.2
// 5.5
// 1
// 10
// 11
// 45.2
// 5.5
// 1
// 私有方法
// 保护方法

12.2 知识点代码

Lesson12A.h

#pragma once
#include <iostream>
using namespace std;

class Lesson12B;

class Lesson12A
{
public:
    int i2 = 11;
    double d = 45.2;
    void showLesson12BInfo(Lesson12B& b);

private:
    int i = 10;
    float f = 5.5f;
    void testPrivate()
    {
        cout << "私有方法" << endl;
    }
protected:
    bool b = true;
    void testProtected()
    {
        cout << "保护方法" << endl;
    }

    //让另一个类成为我的朋友 这样它就可以访问我内部的私有、保护的成员了
    friend class Lesson12B;
};

Lesson12A.cpp

#include "Lesson12A.h"
#include "Lesson12B.h"

void Lesson12A::showLesson12BInfo(Lesson12B& b)
{
    //b.ib //报错 友元类只是单向
}

Lesson12B.h

#pragma once
class Lesson12A;

class Lesson12B
{
private:
    int ib = 111;
public:
    void showLesson12AInfo(const Lesson12A& a);
    void showLesson12AInfo2(Lesson12A& a);

    //friend class Lesson12A;//需要声明后A才能是B的友元类 只声明B是A的友元类不是双向的
};

Lesson12B.cpp

#include "Lesson12B.h"
#include "Lesson12A.h"
#include <iostream>
using namespace std;

void Lesson12B::showLesson12AInfo(const Lesson12A& a)
{
    cout << a.i << endl;
    cout << a.i2 << endl;
    cout << a.d << endl;
    cout << a.f << endl;
    cout << a.b << endl;
    //const对象参数 只能点出const方法 普通方法不能用
}
void Lesson12B::showLesson12AInfo2(Lesson12A& a)
{
    cout << a.i << endl;
    cout << a.i2 << endl;
    cout << a.d << endl;
    cout << a.f << endl;
    cout << a.b << endl;
    a.testPrivate();
    a.testProtected();
}

Lesson12_面向对象_封装_友元类.cpp

#include <iostream>
#include "Lesson12A.h"
#include "Lesson12B.h"
int main()
{
    #pragma region 知识点一 友元类的概念
    //友元类是允许一个类访问另一个类的私有(private)和保护(protected)成员
    //友元类的作用类似于友元函数,但是它赋予了整个类访问权限,而不仅限于某个函数
    #pragma endregion

    #pragma region 知识点二 友元类的使用
    //规则:
    //1.在一个类中利用friend关键字让一个类成为该类的友元 
    //	friend class 另一个类类名;
    //2.一个类成为了另一个类的友元类后,就可以在其中访问另一个类的私有或保护成员了
    //注意:
    //1.友元关系不能逆向,除非互为友元
    //2.友元关系不能传递,即父类为一个类的友元,它的子类并不继承这个关系

    Lesson12A a;
    Lesson12B b;
    b.showLesson12AInfo(a);
    b.showLesson12AInfo2(a);
    //10
    //11
    //45.2
    //5.5
    //1
    //10
    //11
    //45.2
    //5.5
    //1
    //私有方法
    //保护方法

    #pragma endregion
}

12.3 练习题

简要说明友元类有什么作用

友元类的作用:允许一个类访问另一个类的私有成员和保护成员。实现了类与类之间的紧密协作。
开发中我们一般会利用友元类来做什么:

  1. 工厂模式,会使用友元类来调用对象的私有构造函数,通过工厂来管理创建这些对象
  2. 调试程序或测试程序时,会利用友元类来获取类中的一些私有或保护的信息
  3. 操作类/工具类,可以利用它们去访问一些对象的私有和保护的成员
  4. 等等

实现一个工厂类,它可以调用零件类的私有构造,用于创建零件对象

#pragma once
#include "MonsterFactory.h"

// 怪物类
class Monster
{
private:
    Monster() 
    {
    }

    friend class MonsterFactory;
};
#pragma once

// 怪物工厂:专门用来管理游戏中的怪物
// 比如怪物的创建、怪物的移除、怪物的记录
class Monster;
class MonsterFactory
{
public:
    // 创建怪物(可以改为堆上分配)
    Monster createMonster();
    // 还会有移除怪物的方法
    // 如果怪物都在堆上分配,那么内存管理又应该通过怪物工厂如何去管理呢?
};
#include "Monster.h"
#include "MonsterFactory.h"

Monster MonsterFactory::createMonster()
{
    return Monster();
}
MonsterFactory monsterFactory;
Monster monster = monsterFactory.createMonster();

12.4 练习题代码

MonsterFactory.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();
}

Lesson12_练习题.cpp

#include <iostream>
#include "Monster.h"

int main()
{
    #pragma region 练习题一
    //请简要说明友元类有什么作用
    // 
    //友元类的作用:允许一个类访问另一个类的私有成员和保护成员。实现了类与类之间的紧密协作。
    //开发中我们一般会利用友元类来做什么:
    //1.工厂模式,会使用友元类来调用对象的私有构造函数,通过工厂来管理创建这些对象
    //2.调试程序或测试程序时,会利用友元类 来获取类中的一些私有或保护的信息
    //3.操作类/工具类,可以利用他们去访问一些对象的私有和保护的成员
    //等等
    #pragma endregion

    #pragma region 练习题二
    //请实现一个工厂类,它可以调用零件类的私有构造,用于创建零件对象
    MonsterFactory monsterFactory;
    Monster monster = monsterFactory.createMonster();
    #pragma endregion
}


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

×

喜欢就点赞,疼爱就打赏