Fork me on GitHub

友元函数

-----------------siwuxie095

   

   

   

   

   

   

   

   

C++ 中,存在着一种朋友关系,这种朋友关系如果体现在函数上,

就称之为 友元函数,如果体现在类上,就称之为 友元类

   

   

   

这里介绍 友元函数

   

   

   

   

友元函数

   

   

就定义函数的情形来说,一种是将其定义为全局函数,另一种

是将其定义在类中,使它成为类的成员函数

   

   

   

   

当把全局函数声明为友元函数,就称之为 友元全局函数,当把

成员函数声明为另一个类的友元函数,就称之为 友元成员函数

   

   

   

   

   

   

   

   

友元全局函数

   

   

看如下实例:

   

定义一个坐标类:Coordinate

   

   

   

   

如果想要定义一个友元函数,就要使用关键字:friend

   

使用方法:通过关键字 friend 接友元函数

   

友元函数其实就是一个函数的声明,声明的最后以分号结尾,同时一定

要传入当前类的对象 或引用 或指针,总之,要能通过该函数访问到对象

中私有的数据成员 保护的数据成员

   

   

   

友元函数的使用方法:

   

   

   

printXY() 即 打印横纵坐标,需要传入一个 Coordinate 的引用,

访问时,可以直接访问私有数据成员

   

如果没有将 printXY() 声明为 Coordinate 的友元,那么直接访

问私有数据成员,编译器就会报错

   

注意:传入引用 指针,传递效率更高,执行速度更快,提倡

传入 引用 指针,而不提倡直接传入 对象

   

   

main() 函数中调用 printXY() 时,需要先实例化一个 Coordinate

的对象,然后将该对象传递进去即可

   

   

   

   

友元成员函数

   

   

看如下实例:

   

   

   

此时仍然使用关键字:friend,但注意后面的写法:

   

使用的函数仍然是 printXY(),但此时 printXY() 并不是一个全局函数,

而是 Circle 类中的成员函数,如果要将 Circle 类的 printXY() 声明为

Coordinate 类的友元函数,需要将 Circle 写出来,后面接 ::,后面再

接 printXY()

   

   

   

在使用时:

   

Circle 类中 printXY() 的实现方法和前面的实现方法基本相同

   

   

   

   

友元给我们带来方便的同时,也带来了一些风险:

   

当在 Coordinate 类中将 Circle 类的 printXY() 声明为它的友元之后,

也就破坏了 Coordinate 类的封装性。破坏了封装性之后,对于数据

的直接访问虽然是方便了,但是如果不小心改变了数据的值,也不易

察觉

   

所以,风险和方便往往是相互矛盾的。除非有特殊的需要,否则一般

情况下,不建议处处使用友元,把友元当做自己知识的一种炫耀

   

   

   

   

   

程序:

   

   

Match.h:

   

#ifndef MATCH_H

#define MATCH_H

   

#include <iostream>

using namespace std;

   

   

class Time;//注意这里要声明

class Match

{

public:

//声明printTime2()时要用到 Time

//所以必须要在 Match 的上面通过 Time 声明一下,

//有这样一个类,后面的时候会定义

void printTime2(Time &t);

};

   

#endif

   

   

   

Match.cpp:

   

#include "Match.h"

#include "Time.h"

   

void Match::printTime2(Time &t)

{

cout << t.m_iHour << ":" << t.m_iMinute << ":" << t.m_iSecond << endl;

}

   

   

   

Time.h:

   

#ifndef TIME_H

#define TIME_H

   

#include "Match.h"//这里要加上Match的头文件

#include <iostream>

using namespace std;

   

   

class Time

{

//作为友元函数来说,位置并没有约束,写在哪里都行,

// friend 的友元声明,与访问限定符并不形成交叉关系

//

//建议写在类的最前边,因为对于类来说,对外如何进行暴露是非常重要的

//把重要的信息放在前边有助于编程过程中减小犯错的概率

friend void printTime1(Time &t);//友元全局函数

friend void Match::printTime2(Time &t);//友元成员函数

   

public:

Time(int hour, int min, int sec);

private:

int m_iHour;

int m_iMinute;

int m_iSecond;

};

   

#endif

   

   

   

Time.cpp:

   

#include "Time.h"

   

Time::Time(int hour, int min, int sec)

{

m_iHour = hour;

m_iMinute = min;

m_iSecond = sec;

}

   

   

   

main.cpp:

   

#include "stdlib.h"

#include "Time.h"

#include "Match.h"

   

//提倡把函数的声明写在前面,定义写在后面

void printTime1(Time &t);

   

int main(void)

{

Time t(6, 34, 25);

printTime1(t);

Match m;

m.printTime2(t);

system("pause");

return 0;

}

   

//通过声明友元,就能使得传入进来的对象

//去访问它私有的数据成员和成员函数

void printTime1(Time &t)

{

cout << t.m_iHour << ":" << t.m_iMinute << ":" << t.m_iSecond << endl;

}

   

   

   

   

   

   

   

   

   

   

【made by siwuxie095】

posted on 2017-05-05 16:49  siwuxie095  阅读(329)  评论(0编辑  收藏  举报

导航