12.面向对象-封装-友元类
12.1 知识点
友元类的概念
- 友元类是允许一个类访问另一个类的私有 (private) 和保护 (protected) 成员
- 友元类的作用类似于友元函数,但是它赋予了整个类访问权限,而不仅限于某个函数
友元类的使用
- 规则: - 在一个类中利用 friend关键字让一个类成为该类的友元
 - friend class 另一个类类名;
- 在一个类中利用 
- 一个类成为了另一个类的友元类后,就可以在其中访问另一个类的私有或保护成员了
 
 
- 注意: - 友元关系不能逆向,除非互为友元
 
- 友元关系不能传递,即父类为一个类的友元,它的子类并不继承这个关系
 
 
代码示例:
#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 练习题
简要说明友元类有什么作用
友元类的作用:允许一个类访问另一个类的私有成员和保护成员。实现了类与类之间的紧密协作。
开发中我们一般会利用友元类来做什么:
- 工厂模式,会使用友元类来调用对象的私有构造函数,通过工厂来管理创建这些对象
- 调试程序或测试程序时,会利用友元类来获取类中的一些私有或保护的信息
- 操作类/工具类,可以利用它们去访问一些对象的私有和保护的成员
- 等等
实现一个工厂类,它可以调用零件类的私有构造,用于创建零件对象
#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
 
            