C++语言学习(七)――友元

匿名 (未验证) 提交于 2019-12-03 00:41:02
C++语言学习(七)――友元

一、友元简介

1、友元简介

面向对象编程的类的设计机制实现了数据的隐藏与封装,类的成员变量一般定义为私有成员,成员函数一般定义为公有的,是类与外部的通信接口。在实践中,类外的某些函数需要频繁地访问类的成员变量,可以将类外的函数定义为类的友元函数。除了友元函数外,还有友元类,两者统称为友元。友元的作用是提高了程序的运行效率(即减少了类型检查和安全性检查等都需要时间开销),但友元破坏了类的封装性和隐藏性,使得非类的成员函数可以访问类的私有成员。
友元是C++语言中的一种关系,友元关系发生在函数与类之间或者类与类之间。友元关系是单向的,不能传递。
与类有友元关系的函数称为友元函数,与类有友元关系的类称为友元类。

2、友元的特性

友元的特性如下:
A、在类中以friend关键字声明友元
B、类的友元可以是其它类或具体函数
C、友元不是类的一部分
D、友元不受类中访问级别的限制
E、友元可以直接访问具体类的所有成员
F、友元关系不能被继承
G、友元关系是单向的,不具交换性
H、友元关系不具有传递性

3、友元的本质

友元的本质,是让其它不属于本类的成员(全局函数,其它类的成员函数,其它类),成为本类的成员而具备本类成员的属性。

二、友元函数

1、友元函数简介

友元函数是可以直接访问类的私有成员的非成员函数,是定义在类外的函数,可以是不属于任何类的全局函数或是其它类的成员函数,但需要在类的定义中加以声明。

2、全局函数为友元函数

全局函数作为类的友元声明时只需在友元的名称前加上关键字friend,其格式如下:
friend 类型 函数名(形式参数);
一个函数可以是多个类的友元函数,只需要在各个类中分别声明。

#include <iostream> #include <cmath>  using namespace std;  class Point { public:     Point(double x = 0, double y = 0)     {         this->x = x;         this->y = y;     }     void printPoint()     {         cout << "(" << x << "," << y << ")";     }     //友元函数声明     friend double getDistance(const Point &a, const Point &b); private:     double x;     double y; };  double getDistance(const Point &a, const Point &b) {     double dx = a.x - b.x;     double dy = a.y - b.y;     return sqrt(dx*dx + dy*dy); }  int main(int argc, char *argv[]) {     Point a(0,0);     Point b(1,8);     cout << "Point";     a.printPoint();     cout << " and Point";     b.printPoint();     cout << " has distance at "<< getDistance(a, b) << endl;     return 0; }

3、类成员函数为友元函数

类成员函数作为类的友元声明时只需在友元的名称前加上关键字friend,其格式如下:
friend 类型 类名::函数名(形式参数);
一个函数可以是多个类的友元函数,只需要在各个类中分别声明。

#include <iostream> #include <cmath>  using namespace std;  class Point;  class ManagerPoint { public:     double getDistance(const Point &a, const Point &b); };  class Point { public:     Point(double x = 0, double y = 0)     {         this->x = x;         this->y = y;     }     void printPoint()     {         cout << "(" << x << "," << y << ")";     }     //友元函数声明     friend double ManagerPoint::getDistance(const Point &a, const Point &b); private:     double x;     double y; };  double ManagerPoint::getDistance(const Point &a, const Point &b) {     double dx = a.x - b.x;     double dy = a.y - b.y;     return sqrt(dx*dx + dy*dy); }  int main(int argc, char *argv[]) {     ManagerPoint manager;     Point a(0,0);     Point b(1,8);     cout << "Point";     a.printPoint();     cout << " and Point";     b.printPoint();     cout << " has distance at "<< manager.getDistance(a, b) << endl;     return 0; }

上述代码中使用了类的前向声明。前向声明,是一种不完全型(forward declaration)声明,即只需提供类名(无需提供类实现)即可。前向声明功能有限:
A、不能定义类的对象。
B、可以用于定义指向这个类型的指针或引用。
C、用于声明(不是定义)使用该类型作为形参或者返回类型的函数。

三、友元类

友元类的所有成员函数都是另一个类的友元函数,都可以访问另一个类中的隐藏信息(包括私有成员和保护成员)。当希望一个类可以访问另一个类的私有成员、保护成员时,可以将该类声明为另一类的友元类。
定义友元类的语句格式如下:
friend class 类名;
friend和class是关键字,类名必须是程序中的一个已定义的类。

#include <iostream> #include <cmath>  using namespace std;  class Point;  class ManagerPoint { public:     double getDistance(const Point &a, const Point &b); };  class Point { public:     Point(double x = 0, double y = 0)     {         this->x = x;         this->y = y;     }     void printPoint()     {         cout << "(" << x << "," << y << ")";     }     //友元类声明     friend class ManagerPoint; private:     double x;     double y; };  double ManagerPoint::getDistance(const Point &a, const Point &b) {     double dx = a.x - b.x;     double dy = a.y - b.y;     return sqrt(dx*dx + dy*dy); }  int main(int argc, char *argv[]) {     ManagerPoint manager;     Point a(0,0);     Point b(1,8);     cout << "Point";     a.printPoint();     cout << " and Point";     b.printPoint();     cout << " has distance at "<< manager.getDistance(a, b) << endl;     return 0; }
ManagerPoint类的所有成员函数都是类Point的友元函数,能访问类Point的私有成员和保护成员。

原文:http://blog.51cto.com/9291927/2143190

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!