王桂林讲C++之友元

王桂林老师C++之友元

友元,英语为friend,朋友的意思,朋友就是关系亲密的两个人,能够分享物品的两个人。
由此可见,友元在C++之中的作用,就是实现数据的方便访问。
本文将从下面三个方面来阐述friend的功能:

  • 在什么情况下,使用友元能够带来方便?
  • 友元可以修饰哪几种类型?
  • 友元注意事项?

在什么情况下,使用友元能够带来方便?

先举一个生活中的例子。A和B是借贷关系,每次A找B贷款,都需要得到B的同意,这样做很符合规矩。但是,有时候A频繁的找B借钱,这样B就频繁的接待A,很耽误自己的时间,而且也很麻烦。B就开始想办法解决这个麻烦,他觉得A值得信任,可以做他的朋友,于是就告诉A,以后你来找我借钱,就直接到一个地方拿,不需要经过我的允许。这样,麻烦就解决了。但是,也导致了不安全。
同样,在C++中,也是一样的道理。先定义一个类B:

//main.cpp
class B
{
public:
    int getX()
    {
        return x;
    }
private:
    int x;
};

void func()
{
    B b;
    for (int i=0; i<10000; i++)
    {
        std::cout<<b.getX()<<std::endl;  //只能通过接口访问类私有成员
    }
}

因为类的私有成员不能直接被访问,所以func函数访问B中的x,就必须要经过B的公共成员函数getX。但是如果将func声明为B的友元,则就可以通过B的对象直接访问x。修改如下,

class B
{
public:
    friend void func(B & b);  //友元函数声明(注意:友元函数不受public、private的影响,一般习惯放在public下)
private:
    int x;
};
//友元函数定义
void func(B & b)
{
    for (int i=0; i<10000; i++)
    {
        std::cout<<b.x<<std::endl;     //直接通过类对象访问私有成员
    }
}

友元可以修饰哪几种类型?

从上一段中可以得知,全局函数可以成为类的友元。除了全局函数外,还有不同类的成员函数、类的对象都可以成为一个类的友元。

//A类的成员函数为B类的友元函数
//main.cpp
class B;   //因为类A中使用了B的引用,所以必须要在类A之前进行这种不完全声明。(注意:不完全声明后,只能使用其引用和指针。)
class A
{
public:
    int getadd(B & b);
};

class B
{
public:
    friend int A::getadd(B & b);  //格式基本与全局函数声明一致,只是函数前加上类命名空间
private:
    int x;
    int y;
};

int A::getadd(B & b)
{
    return (b.x + b.y);
}

假如类A的所有成员函数,都是去操作类B的成员变量。为了方便,可以直接把A声明为B的友元,这样就不需要一个函数一个函数的声明了。

//A类为B类的友元函数
//main.cpp
class B;
class A
{
public:
    int getadd(B & b);
    int getsub(B & b);
};

class B
{
public:
    friend A;
private:
    int x;
    int y;
};

int A::getadd(B & b)
{
    return (b.x + b.y);
}
int A::getsub(B & b)
{
    return (b.x - b.y);
}

友元注意事项?

  1. 友元关系不能够被继承。
  2. 友元关系是单向的,不具有交换性。如果类A是类B的友元,那么类B不一定是类A的友元,要看类中是否有相关的声明。
  3. 友元关系不具备传递性。如果类A是类B的友元,类C是类A的友元,那么类C不一定是类B的友元,要看类中是否有相关的声明。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值