[原]友元函数 友元类 友元成员函数

王良 18/05/07 22:34:40

友元

一般来说,类内的私有数据是对外不可见的,但在有些情况下,我们需要在类外对该类的私有数据进行访问,这就需要用到一种新技术——友元(friend),即在声明前添加关键字friend

友元关系是单向的,即如果A是B的友元,但B不一定是A的友元;
友元关系无传递性,即如果A是B的友元,B是C的友元,但A不一定是C的友元。


1. 友元函数

友元函数是指某些非类成员函数,但可以访问类内的私有数据。

#include <iostream>
using namespace std;

class A {
private:
    int data;
public:
    A() : data(1) {}
    friend void show( const A& t );  //添加friend定义友元函数
};  

/* 友元函数在类外声明时不加friend */
void show( const A& t ) {
    cout << "data = " << t.data << endl;  
}

int main(void) {  
    A a;
    show(a);  

    return 0;  
}

/*

运行结果:
data = 1

*/

2. 友元类

友元类是指若需要在类B中直接访问类A的私有数据,因此将B作为A的友元(在A中声明friend class B;)。
友元类中的成员函数、私有数据都可以在另一个类中被使用(即类B中可以直接使用类A的私有数据等)

class Tv {
private: 
    int state;
public: 
    friend class Remote;  //声明Remote为Tv的友元类
    enum{ Off, On };

    Tv( int s = Off ) : state(s) {}
    void onoff() { state = (state == On) ? Off : On; }
};

class Remote {
public: 
    void onoff( Tv & t ) { t.onoff(); }
};

3. 友元成员函数

友元成员函数是指类中的一个成员函数被定义为友元函数。
与友元类不同的是,只有友元成员函数可以在另一个中被使用,其余函数都不可以。

#include <iostream>
using namespace std;

class B;  //前向声明

class A{
private: 
    int a;
public: 
    A() { a = 1; }
    void print( B & b );
};

/* 示例位置1 */

class B{
private: 
    int b;
public: 
    B() { b = 6; }
    void print() { cout << b << endl; }
    friend void A::print( B & b );  //友元成员函数
};

/* 被定义为友元成员函数的函数必须在类外(另一个使用该函数的类后面)定义 */
void A::print( B & b ) {
    cout << "b = " << b.b << endl;
}

int main() {
    A a;
    B b;
    a.print( b );

    return 0;
}

/*

输出结果:
b = 6

*/

需要注意的是:
(1)类的前向声明。由于在A中的print函数需要使用B,如果不进行B的前向声明,编译器就不知道B是一个类,会报错。
(2)类的排列顺序。在类B中会用到A的方法print(),因此需要先定义A,再定义B。
(3)友元成员函数的定义位置。友元成员函数不能使用内联代码,类中只能有函数声明。函数定义需要放到类之后,在类外进行定义,而且必须放到另一个类定义的后面。(对上面代码来说,若将A::print()的定义放在类B定义之前——示例位置1处,也会报错,提示类B未完成)

对于友元的位置在何处生明,可以简单记为friend在哪,哪个就可以被外面直接访问。(friend在类A,A就可以被其他特定位置访问)

作者:liushall 发表于 2018/05/07 22:34:40 原文链接 https://blog.csdn.net/liushall/article/details/80232819
阅读:54