C++友元类和友元函数

友元类有以下两个特点:

(1)如果B声明成A的友元类,那么B可以访问A的protected、private成员。但是A不能访问B的protected、private成员。

(2)如果C继承B,C不能访问A的protected、private数据成员和函数,只能访问A的public成员。但是可以通过B的公共接口获取到A的protected、private信息。

友元函数有以下两个特点:

(1)定义在类外部,但有权访问类的所有私有(private)成员和保护(protected)成员。

(2)虽然友元函数的原型有在类的定义中出现,但是友元函数并不是成员函数。

现在参照以下代码深入分析:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>

class Father;
class Mother;

class Father
{
public:
    Father()
    {
        m_nAge = 1;
        m_nWeChat = 1;
        m_nSalary = 1;
    }

    ~Father() 
    {
        m_nAge = 0;
        m_nWeChat = 0;
        m_nSalary = 0;
    }

    friend class Mother;  //Mother是Father的友元类,可以访问father的private、protected成员
    friend void GetFatherSalary(Father& tFather); //友元函数,可以访问father的private、protected成员

public:
    void PrintfAge()
    {
        printf("Father's age is 30.\n");
    }


    //void FatherGetMotherInfo(Mother &tMother)
    //{
    //    printf("Father get mother info\n");
    //    //只能访问Mother的public成员
    //    printf("Mother public    m_nSex    :   [%d]\n", tMother.m_nSex);
    //    printf("------------------\n\n");
    //}

private:
    void PrintfSalay()
    {
        printf("Father's salary is $2000.\n");
    }

public:
    int m_nAge; //年龄

protected:
    int m_nWeChat; //微信

private:
    int m_nSalary; //工资
};

class Mother
{
public:
    Mother()
    {
        m_nSex = 2;
        m_nQQ = 2;
        m_nPayCard = 2;
    }

    ~Mother()
    {
        m_nSex = 0;
        m_nQQ = 0;
        m_nPayCard = 0;
    }

public:
    void MotherGetFatherInfo(Father &tFather)
    {
        //Mother是Father的友元类,可以访问Father的public、protected、private成员和函数
        printf("Father public    m_nAge    :   [%d]\n", tFather.m_nAge);
        printf("Father protected m_nWeChat :   [%d]\n", tFather.m_nWeChat);
        printf("Father private   m_nSalary :   [%d]\n", tFather.m_nSalary);

        tFather.PrintfAge();
        tFather.PrintfSalay();
    }

public:
    int m_nSex; //性别

protected:
    int m_nQQ; //QQ

private:
    int m_nPayCard; //工资卡
};


class Son : public Mother
{
public:
    Son()
    {
        m_nGirlFriend = 3;
    }

    ~Son()
    {
        m_nGirlFriend = 0;
    }

public:
    void SonGetFatherInfo(Father &tFather)
    {
        printf("Father public    m_nAge    :   [%d]\n", tFather.m_nAge);

        //友元关系不能被继承,所以没法访问Father的m_nWeChat、m_nSalary、PrintfSalay等protected和private成员、函数
        //printf("Father protected m_nWeChat :   [%d]\n", tFather.m_nWeChat);  
        //printf("Father private   m_nSalary :   [%d]\n", tFather.m_nSalary);

        tFather.PrintfAge();
        //tFather.PrintfSalay();
    }


    void SonGetFatherInfoByMother(Father& tFather)
    {
        MotherGetFatherInfo(tFather);//虽然自己获取不到Father私有信息,可以通过Mother获取Father私有信息
    }

private:
    int m_nGirlFriend;

};


void GetFatherSalary(Father &tFather)
{
    //友元函数可以访问father的private、protected成员
    printf("friend function: get father salary[%d]\n", tFather.m_nSalary);
    printf("friend function: get father wechat[%d]\n", tFather.m_nWeChat);
}


int main()
{
    Father tFather;
    Mother tMother;
    Son tSon;

    printf("------------------\n");
    printf("Mother begin get father info......\n");
    tMother.MotherGetFatherInfo(tFather);
    printf("------------------\n\n");

    printf("------------------\n");
    printf("Son begin get father info......\n");
    tSon.SonGetFatherInfo(tFather);
    printf("------------------\n\n");

    printf("------------------\n");
    printf("Son begin get father info by mother......\n");
    tSon.SonGetFatherInfoByMother(tFather);
    printf("------------------\n\n");

    //通过友元函数访问
    GetFatherSalary(tFather);
    return 0;
}

程序运行结果如下:

在上述代码中:

(1)妈妈(Mother)是爸爸(Father)的友元类,那么爸爸在妈妈面前没有任何隐私可言,即妈妈可以访问爸爸的public年龄m_nAge、protected微信m_nWeChat、private工资m_nSalary,而爸爸只能访问妈妈的public性别m_nSex。

(2)儿子继承妈妈,注意的是不能将友元关系继承下来,试想本身友元已经破坏了类的封装特性了,假如友元关系能继承下来,类与类的关系就非常乱了,难以维护这么错综复杂的关系,所以儿子只是继承了妈妈public的成员,同时只能访问爸爸的public年龄m_nAge。但是儿子可以通过妈妈打听到爸爸的收入情况,即妈妈的public函数MotherGetFatherInfo。

(3)有一种情况,爸爸考虑个人隐私,没有将妈妈置为友元类,妈妈就在爸爸那边默默装了个监控,即友元函数void GetFatherSalary(Father &tFather)诞生了,妈妈就能通过GetFatherSalary偷偷监视爸爸的peotected微信和private工资。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值