当前位置: > 嵌入式学院 > 嵌入式学习 > 讲师博文 > 关于C++中的友元
关于C++中的友元
时间:2017-10-26作者:华清远见

1. 起源:

类实现了数据的隐藏与封装,类的数据成员一般定义为私有成员,仅能通过类的成员函数才能读写。如果数据成员定义为公共的,则又破坏了封装性。但是某些情况下,需要频繁读写类的数据成员,特别是在对某些成员函数多次调用时,由于参数传递、类型检查和安全性检查等都需要时间开销,而影响程序的运行效率。

2. 概念:

友元是一种定义在类外部的普通函数,但他需要在类体内进行说明,为了和该类的成员函数加以区别,在说明时前面加以关键字friend。友元不是成员函数,但是他能够访问类中的私有成员。友元的作用在于提高程序的运行效率,但是,他破坏了类的封装性和隐藏性,使得非成员函数能够访问类的私有成员。导致程序维护性变差,因此使用友元要慎用。

友元较为实际的应用是在运算符重载,这种应用可以提高软件系统的灵活性

3. 分类:友元函数、友元成员、友元类

4. 友元函数:

1)概念:是一种说明在类定义体内的非成员函数

2)格式:friend 返回值类型 函数名(参数表){ 函数体 }

3)说明:

A. 友元函数是在类中说明的一个函数,它不是该类的成员函数,但可以访问该类的所有成员,它是独立于任何类的一般的外界函数。

B. 由于不是类的成员,所以没有this指针,访问该类的对象的成员时必须使用对象名,而不能直接使用类的成员名。

C. 虽然友元函数是在类中说明的,但其名字的作用域在类外,作用域的开始点在说明点,结束点和类名相同

【案例1】

#include <iostream>

#include <string.h>

//普通函数可以访问类中的私有成员

using namespace std;

class Grade

{

public:

    Grade(int ch, int ma):chinese(ch), math(ma){}

    friend void show(Grade &gr);//友元函数的说明

private:

    int chinese;

    int math;

};

void show(Grade &gr)//友元函数的实现

{

    cout << "chinese: " << gr.chinese << endl;//没有this,只能用对象调用

    cout << "math: " << gr.math << endl;

}

int main()

{

    Grade gr(89, 90);

    show(gr);//友元函数的调用

    return 0;

}

5. 友元类:

1)概念:某个类可以是另一个类的友元,这样作为友元的类中的所有成员函数都可以访问另一个类中的私有成员。

2)格式:friend class 类名;

【案例2】

#include <iostream>

#include <string.h>

//其他类的所有成员函数都可以访问此类的私有成员:Boy类中的成员函数disp可以访问Girl类中的成员

using namespace std;

class Boy;//在类Name中需要使用类Grade,so先声明

class Girl

{

public:

    Girl(char *n)

    {

        strcpy(name, n);

    }

private:

    char name[32];

    friend class Boy;//类Grade是类Name的友元,so在类grade中可以使用类Name的成员

};

class Boy

{

public:

    void disp(Girl &);

};

void Boy :: disp(Girl &g)

{

    cout << "name: " << g.name << endl;

}

int main()

{

    Boy b;

    Girl g("lily");

    b.disp(g);

    return 0;

}

 

3)特点:

A. 友元关系不能被继承。

B. 友元关系是单向的,不具有交换性。若类B是类A的友元,类A不一定是类B的友元,要看在类中是否有相应的声明。

C. 友元关系不具有传递性。若类B是类A的友元,类C是B的友元,类C不一定是类A的友元,同样要看类中是否有相应的申明

6. 友元成员函数:

1)概念:另一个类的成员函数可以作为某个类的友元,只是在声明友元函数时要加上成员函数所在的类名。

2)格式:friend 类名 :: 成员函数名;

【案例3】

#include <iostream>

#include <string.h>

//其他类的一个成员函数都可以访问此类的私有成员:Boy类中的成员函数disp可以访问Girl类中的成员

using namespace std;

class Girl;//在类Name中需要使用类Grade,so先声明

class Boy

{

public:

    Boy(int a):age(a){}

    void disp(Girl &);

private:

    int age;

};

class Girl

{

public:

    Girl(char *n)

    {

        strcpy(name, n);

    }

    friend void Boy :: disp(Girl &);//声明Boy类中的成员函数为友元函数

                                   //可以访问Girl类中的成员

private:

    char name[32];

};

void Boy :: disp(Girl &g)

{

    cout << "girl's name: " << g.name << endl;

    cout << "boy's age: " << age << endl;

}

int main()

{

    Boy b(22);

    Girl g("lily");

    b.disp(g);

    return 0;

}


发表评论
前台专线:010-82525158 企业培训洽谈专线:010-82525379 院校合作洽谈专线:010-82525379 Copyright © 2004-2018 北京华清远见科技发展有限公司 版权所有 ,京ICP备16055225号,京公海网安备11010802025203号