友元函数和友元类

一个类中可以有 public、protected、private 三种属性的成员,通过对象可以访问 public 成员,只有本类中的函数可以访问本类的 private 成员。在类的外部就没有办法访问类的private成员吗?不是的。现在,我们来介绍一种例外情况——友元(friend)。借助友元(friend),可以使得其他类中的成员函数以及全局范围内的函数访问当前类的 private 成员。

1、友元函数

在当前类以外定义的、不属于当前类的函数也可以在类中声明,但要在前面加 friend 关键字,这样的函数称为友元函数。友元函数可以是不属于任何类的非成员函数,也可以是其他类的成员函数。友元函数可以访问当前类中的所有成员,包括public、protected和private属性的成员。所以,可以说友元函数破坏了类的封装性。

定义方式:

class A
{
 private:
     int i;
     friend void FriendFun(A *ptr,int x);
 public:
     void MemberFun(int x);      
};
...
void FriendFun(A *ptr, int x)
{
     ptr->i = x;
}
void A::MemberFun(int x)
{
     i = x;
}

 说明:

1)友元函数在类中的位置与访问权限无关,即“friend void FriendFun(A *ptr,int x);”语句放在private或者public都没有影响;

2)友元函数通过对象参数访问私有成员,即需要输入参数中需要有对象的指针。

下面看一个简单例子:

#include <iostream>
using namespace std;

class TestFriend
{
public:
    TestFriend(int a,int b)
    {
        this->a = a;
        this->b = b;
    }
    int get_a()
    {
        return this->a;
    }
    friend void modifyTest(TestFriend *pT,int a);
private:
    int a;
    int b;
};

void modifyTest(TestFriend *pT,int a)
{
    pT->a = a;
}
int main() {
    TestFriend tf(1,2);
    cout << tf.get_a() << endl;

    modifyTest(&tf,4);
    cout << tf.get_a() << endl;
    return 0;
}

modifyTest()是一个全局范围内的函数,它不属于任何类,它的作用是修改对象pT中的a值,在类TestFriend中a为私有成员,原则上不能通过对象访问,但是加入友元之后便可以访问。

注意:友元函数不同于类成员函数,在友元函数中不能直接访问类的成员,必须借助对象,所以,下面的定义是错误的:

void modifyTest(int a)
{
    TestFriend->a = a;
}

 

2、友元类

将类 B 声明为类 A 的友元类,那么类 B 中的所有成员函数都是类 A 的友元函数。

1)若B类是A类的成员类,则B类的所有成员函数都是A类的友元函数;

2)友元类通常设计为一种数据操作或类之间传递信息的辅助类。

#include <iostream>
using namespace std;


class A
{
    // B类是A类的友元类
    // 在B类中可以访问A类的私有成员、私有函数
    friend class B;
public:
    void printx()
    {
        cout << x << endl;
    }
private:
    int x;
};

class B
{
public:
    void setx(int i)
    {
        Aobject.x = i;
    }
    void printx()
    {
        Aobject.printx();
    }
private:
    A Aobject;
};



int main() {
    B Bobject;
    Bobject.setx(10);
    Bobject.printx();   // 10
    return 0;
}

 

posted @ 2020-08-25 16:03  运运翻牌了Howardy  阅读(247)  评论(0)    收藏  举报