让你我有缘的“友元”

友元的概念:

友元是一种定义在类外部的普通函数或类,但它需要在类体内进行说明,为了与该类的成员函数加以区别,在说明时前面加以关键字friend。友元不是成员函数,但是它可以访问类中的私有成员。

友元的背景:

类具有封装和信息隐藏的特性。只有 类的成员函数 才能访问类的私有成员,程序中的其他函数是无法访问私有成员的。非成员函数可以访问类中的公有成员,但是如果将 数据成员 都定义为公有的,这又破坏了隐藏的特性。另外,应该看到在某些情况下,特别是在对某些成员函数多次调用时,由于 参数传递 ,类型检查和安全性检查等都需要时间开销,而影响程序的运行效率。

为了解决上述问题,提出一种使用友元的方案。友元是一种定义在类外部的普通函数或类,但它需要在类体内进行说明,为了与该类的成员函数加以区别,在说明时前面加以关键字friend。友元不是成员函数,但是它可以访问类中的私有成员。友元的作用在于提高程序的运行效率,但是,它破坏了类的封装性和隐藏性,使得非成员函数可以访问类的私有成员。不过,类的访问权限确实在某些应用场合显得有些呆板,从而容忍了友元这一特别语法现象

友元的目的:

友元的目的就是让一个函数或者类访问另一个类内的私有成员

友元的关键字及其语法:

关键字:friend
语法: friend (数据类型 + 函数名) / 类名

友元的相关注意事项:

(1) 友元关系不能被继承。
(2) 友元关系是单向的,不具有交换性。若类B是类A的友元,类A不一定是类B的友元,要看在类中是否有相应的声明。
(3) 友元关系不具有传递性。若类B是类A的友元,类C是B的友元,类C不一定是类A的友元,同样要看类中是否有相应的申明。

友元的三种用法:

  • 全局函数做友元

  • 类做友元

  • 成员函数做友元

  1. 全局函数做友元:

#include <iostream>
#include <string>

using namespace std;

// 房屋类
class Building
{
    // 告诉编译器 laoWang全局函数是 Building类  的好朋友,可以访问Building对象的私有成员
    friend void NearDoor_Mr_wang1(Building *building);
    friend void NearDoor_Mr_wang2(Building &building);
    friend void NearDoor_Mr_wang3(Building building);

public:

    Building()
    {
        m_SittingRoom = "客厅";
        m_BedRoom = "卧室";
    }
    
    string m_SittingRoom;    // 客厅

private:

    string m_BedRoom;        // 卧室
};



//全局函数
void NearDoor_Mr_wang1(Building *building)
{
    cout << "隔壁老王 全局函数 正在访问:(地址传递) " << building->m_SittingRoom << endl;

    cout << "隔壁老王 全局函数 正在访问:(地址传递) " << building->m_BedRoom << endl;
}

void NearDoor_Mr_wang2(Building &building)
{
    cout << "隔壁老王 全局函数 正在访问:(引用传递) " << building.m_SittingRoom << endl;

    cout << "隔壁老王 全局函数 正在访问:(引用传递) " << building.m_BedRoom << endl;
}

void NearDoor_Mr_wang3(Building building)
{
    cout << "隔壁老王 全局函数 正在访问:( 值传递 ) " << building.m_SittingRoom << endl;

    cout << "隔壁老王 全局函数 正在访问:( 值传递 ) " << building.m_BedRoom << endl;
}

void test01()
{
    Building building;
    NearDoor_Mr_wang1(&building);
    NearDoor_Mr_wang2(building);
    NearDoor_Mr_wang3(building);
}


int main()
{
    test01();
}

  1. 类做友元:

#include <iostream>
#include <string>

using namespace std;

// 类作友元

class Building;
class Mr_wang
{
public:

    Mr_wang();

    void visit();    //参观函数  访问Building中的属性

    Building * building;


private:


};

// 房屋类
class Building
{
    // 告诉编译器,LaoWang类是Building类的好朋友,可以访问Building类的私有成员
    friend class Mr_wang;
public:
    
    Building();
        
    string m_SittingRoom;    // 客厅
    
private:
    
    string m_BedRoom;        // 卧室
};

// 类外定义成员函数

Building::Building()
{
    m_SittingRoom = "客厅";
    m_BedRoom = "卧室";
}

Mr_wang::Mr_wang()
{
    // 创建建筑物对象
    building = new Building;
}

void Mr_wang::visit()
{
    cout << "隔壁老王Mr_wang类正在访问:" << building->m_SittingRoom << endl;

    cout << "隔壁老王Mr_wang类正在访问:" << building->m_BedRoom << endl;
}

void test01()
{
    Mr_wang w;
    w.visit();
}

int main()
{
    test01();

    return 0;
}

  1. 成员函数做友元:

#include <iostream>
#include <string>

using namespace std;

class Building;

class Mr_wang
{
public:

    Mr_wang();
    void visit1();    //让visit1()函数   可以 访问Building中的私有成员
    void visit2();    //让visit2()函数 不可以 访问Building中的私有成员

    Building *building;

private:

    
};

class Building
{
    // 告诉编译器,Mr_wang类下的visit1()函数是Building类的好朋友,可以访问Building的私有成员
    friend void Mr_wang::visit1();

public:
    Building();

    string m_SittingRoom;    //客厅
private:

    string m_BedRoom;        //卧室
};


Mr_wang::Mr_wang()
{
    building = new Building;
}

void LaoWang::visit1()
{
    cout << "隔壁老王Mr_wang类中的visit1()函数正在访问:" << building->m_SittingRoom << endl;
    cout << "隔壁老王Mr_wang类中的visit1()函数正在访问:" << building->m_BedRoom << endl;
}

void LaoWang::visit2()
{
    cout << "隔壁老王Mr_wang类中的visit2()函数正在访问:" << building->m_SittingRoom << endl;
    //cout << "隔壁老王Mr_wang类中的visit2()函数正在访问:" << building->m_BedRoom << endl;    //错误!私有属性不可访问
}

Building::Building()
{
    m_SittingRoom = "客厅";
    m_BedRoom = "卧室";
}

void test01()
{
    Mr_wang w;
    
    w.visit1();

    w.visit2();
}

int main()
{
    test01();
    
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值