-
2019-09-10 10:29:08
概念
友元是提供了普通函数或者类中其他成员函数访问另一个类的私有或者保护成员的机制.
- 友元函数:普通函数访问某类中的私有或者保护成员,其不是类的成员函数. 调用时候通过传入类对象来实现,只是表述为友元函数,表明该函数对类中的成员有访问权限.并且函数定义在类外(和普通函数相同),只是在类中声明.
- 友元类: 类中成员函数访问另一类的私有或者保护成员
特点
- 提高了程序的运行效率
- 破坏了类的封装性和隐藏性,使得非成员函数可以访问类的私有成员
知识点
- 友元关系没有继承性,即子类不继承父类的友元函数
- 友元关系没有传递性,不能通过中间的类或者实例来传递友元关系.
- 友元关系没有交换性,即A是B的友元,可以访问B中的私有成员,但B并不一定是A的友元
更多相关内容 -
C++之友元:友元函数和友元类详解
2021-01-20 06:38:05二、友元函数友元函数在类作用域外定义,但它需要在类体中进行说明为了与该类的成员函数加以区别,定义的方式是在类中用关键字friend说明该函数,格式如下: friend 类型 友元函数名(参数表);友元的作用在于提高... -
C++之中的友元函数的作用
2017-12-09 17:23:22友元提供了不同类的成员函数之间、类的成员函数与一般函数之间进行数据共享的机制。通过友元,一个不同函数或另一个类中的成员函数可以访问类中的私有成员...友元函数 :友元函数是可以直接访问类的私有成员的非成员函友元提供了不同类的成员函数之间、类的成员函数与一般函数之间进行数据共享的机制。通过友元,一个不同函数或另一个类中的成员函数可以访问类中的私有成员和保护成员。c++中的友元为封装隐藏这堵不透明的墙开了一个小孔,外界可以通过这个小孔窥视内部的秘密。
友元的正确使用能提高程序的运行效率,但同时也破坏了类的封装性和数据的隐藏性,导致程序可维护性变差。
友元函数 :友元函数是可以直接访问类的私有成员的非成员函数。它是定义在类外的普通函数,它不属于任何类,但需要在类的定义中加以声明,声明时只需在友元的名称前加上关键字friend,其格式如下:
friend 类型 函数名(形式参数);友元函数的声明可以放在类的私有部分,也可以放在公有部分,它们是没有区别的,都说明是该类的一个友元函数。 一个函数可以是多个类的友元函数,只需要在各个类中分别声明。 友元函数的调用与一般函数的调用方式和原理一致。
友元类 :
友元类的所有成员函数都是另一个类的友元函数,都可以访问另一个类中的隐藏信息(包括私有成员和保护成员)。
当希望一个类可以存取另一个类的私有成员时,可以将该类声明为另一类的友元类。定义友元类的语句格式如下:
friend class 类名;
其中:friend和class是关键字,类名必须是程序中的一个已定义过的类。1: #include <iostream> 2: using namespace std; 3: 4: class Radius 5: { 6: friend class Circle; //声明Circle为Radius的友元类 7: friend void Show_r(Radius &n); //声明Show_r为友元函数 8: public: 9: Radius(int x) 10: { 11: r = x; 12: } 13: ~Radius() 14: { 15: } 16: 17: private: 18: int r; 19: }; 20: 21: void Show_r(Radius &n) 22: { 23: cout<<"圆的半径为: "<<n.r<<endl; //调用Radius对象的私有成员变量r 24: } 25: 26: class Circle 27: { 28: public: 29: Circle() {} 30: ~Circle(){} 31: double area(Radius a) 32: { 33: s = a.r * a.r * 3.1415926; //调用Radius对象的私有成员变量r 34: return s; 35: } 36: private: 37: double s; 38: }; 39: 40: int main(int argc, char *argv[]) 41: { 42: Radius objRadius(9); 43: Circle objCircle; 44: 45: Show_r( objRadius ); 46: cout<<"面积为:"<<objCircle.area(objRadius)<<endl; 47: 48: return 0; 49: }
友元函数是可以直接访问类的私有成员的非成员函数。它是定义在类外的普通函数,它不属于任何类,但需要在类的定义中加以声明,声明时只需在友元的名称前加上关键字friend,其格式如下:
friend 类型 函数名(形式参数);友元函数的声明可以放在类的私有部分,也可以放在公有部分,它们是没有区别的,都说明是该类的一个友元函数。 一个函数可以是多个类的友元函数,只需要在各个类中分别声明。 友元函数的调用与一般函数的调用方式和原理一致。
转载部分:
1、为什么要引入友元函数:在实现类之间数据共享时,减少系统开销,提高效率
具体来说:为了使其他类的成员函数直接访问该类的私有变量 即:允许外面的类或函数去访问类的私有变量和保护变量,从而使两个类共享同一函数 优点:能够提高效率,表达简单、清晰 缺点:友元函数破环了封装机制,尽量不使用成员函数,除非不得已的情况下才使用友元函数。
2、什么时候使用友元函数:
1)运算符重载的某些场合需要使用友元。 2)两个类要共享数据的时候
3、怎么使用友元函数:
友元函数的参数:
因为友元函数没有this指针,则参数要有三种情况: 1、 要访问非static成员时,需要对象做参数;--常用(友元函数常含有参数) 2、 要访问static成员或全局变量时,则不需要对象做参数 3、 如果做参数的对象是全局对象,则不需要对象做参数
友元函数的位置:
因为友元函数是类外的函数,所以它的声明可以放在类的私有段或公有段且没有区别。
友元函数的调用:
可以直接调用友元函数,不需要通过对象或指针
友元函数的分类:
根据这个函数的来源不同,可以分为三种方法:
1、普通函数友元函数:
a) 目的:使普通函数能够访问类的友元 b) 语法:声明位置:公有私有均可,常写为公有 声明: friend + 普通函数声明 实现位置:可以在类外或类中 实现代码:与普通函数相同(不加不用friend和类::) 调用:类似普通函数,直接调用
class INTEGER { private: int num; public: friend void Print(const INTEGER& obj);//声明友元函数 }; void Print(const INTEGER& obj)//不使用friend和类:: { //函数体 } void main() { INTEGER obj; Print(obj);//直接调用 }
2、类Y的所有成员函数都为类X友元函数—友元类
a)目的:使用单个声明使Y类的所有函数成为类X的友元 它提供一种类之间合作的一种方式,使类Y的对象可以具有类X和类Y的功能 具体来说: 前提:A是B的友元(=》A中成员函数可以访问B中有所有成员,包括私有成员和公有成员--老忘) 则:在A中,借助类B,可以直接使用~B . 私有变量~的形式访问私有变量 b)语法:声明位置:公有私有均可,常写为私有(把类看成一个变量) 声明: friend + 类名---不是对象啊 调用: c)代码:
class girl; class boy { private: char *name; int age; public: boy(); void disp(girl &); }; void boy::disp(girl &x) //函数disp()为类boy的成员函数,也是类girl的友元函数 { cout<<"boy's name is:"<<name<<",age:"<<age<<endl;//正常情况,boy的成员函数disp中直接访问boy的私有变量 cout<<"girl's name is:"<<x.name<<",age:"<<x.age<<endl; //借助友元,在boy的成员函数disp中,借助girl的对象,直接访问girl的私有变量 //正常情况下,只允许在girl的成员函数中访问girl的私有变量 } class girl { private: char *name; int age; friend boy; //声明类boy是类girl的友元 public: girl(); }; void main() { boy b; girl g; b.disp(g); //b调用自己的成员函数,但是以g为参数,友元机制体现在函数disp中 }
3、类Y的一个成员函数为类X的友元函数
a)目的:使类Y的一个成员函数成为类X的友元 具体而言:而在类Y的这个成员函数中,借助参数X,可以直接以X。私有变量的形式访问私有变量 b)语法:声明位置:声明在公有中 (本身为函数) 声明:friend + 成员函数的声明 调用:先定义Y的对象y---使用y调用自己的成员函数---自己的成员函数中使用了友元机制 c)代码:
class girl; class boy { private: char *name; int age; public: boy(); void disp(girl &); }; class girl { private: char *name; int age; public: girl(char *N,int A); friend void boy::disp(girl &); //声明类boy的成员函数disp()为类girl的友元函数 }; void boy::disp(girl &x) { cout<<"boy's name is:"<<name<<",age:"<<age<<endl; //访问自己(boy)的对象成员,直接访问自己的私有变量 cout<<"girl's name is:"<<x.name<<",age:"<<x.age<<endl; //借助友元,在boy的成员函数disp中,借助girl的对象,直接访问girl的私有变量 //正常情况下,只允许在girl的成员函数中访问girl的私有变量 } void main() { boy b(); girl g(); b.disp(g); }
4、在模板类中使用友元operator<<(对<<运算符的重载)
a)使用方法:
在模板类中声明:
friend ostream& operator<< <>(ostream& cout,const MGraph<VexType,ArcType>& G);
在模板类中定义:
template<class VexType,class ArcType> ostream& operator<<(ostream& cout,const MGraph<VexType,ArcType>& G) { //函数定义 }
b)注意:
把函数声明非模板函数:
[cpp] view plain copyfriend ostream& operator<< (ostream& cout,const MGraph& G);
把函数声明为模板函数:
[cpp] view plain copyfriend ostream& operator<< <>(ostream& cout,const MGraph<VexType,ArcType>& G);
或:
[cpp] view plain copyfriend ostream& operator<< <VexType,ArcType>(ostream& cout,const MGraph<VexType,ArcType>& G);
说明:
在函数声明中加入operator<< <>:是将operator<<函数定义为函数模板,将函数模板申明为类模板的友员时,是一对一绑定的
实际的声明函数:这里模板参数可以省略,但是尖括号不可以省略
[cpp] view plain copyfriend ostream& operator<< <VexType,ArcType>(ostream& cout,const MGraph<VexType,ArcType>& G);
5、友元函数和类的成员函数的区别:成员函数有this指针,而友元函数没有this指针。
6、记忆:A是B的友元《=》A是B的朋友《=》借助B的对象,在A中可以直接 通过B。成员变量(可以是公有,也可以为私有变量) 的方式访问B
分割线
因为友元函数是类外的函数所以友元函数的声明放在了类外或则类内是没有区别的
友元函数可以直接调用不需要通过对象或者指针 -
解析C++中不能重载为友元函数的四个运算符
2020-12-26 02:40:34C++规定有四个运算符 =, ->, ...那么为什么赋值运算符不可以重载为类的友元函数?像同样都是双目运算符的+为什么它就可以呢? 在讨论这问题之前,先看一测试的程序: 代码如下:#include <iostream>using namespace std; -
c++友元函数与友元类的深入解析
2020-12-31 06:43:03友元函数和友元类的需要:类具有封装和信息隐藏的特性。只有类的成员函数才能访问类的私有成员,程序中的其他函数是无法访问私有成员的。非成员函数可以访问类中的公有成员,但是如果将数据成员都定义为公有的,这又... -
Practice_日期合并输出_友元函数_
2021-09-28 18:59:20采用C++语言实现的日期时间合并输出(友元函数) -
C++运算符重载 成员函数与友元函数详解
2020-09-05 02:44:13以下是对C++运算符重载 成员函数与友元函数进行了介绍,需要的朋友可以过来参考下 -
C++ 友元函数的函数指针
2020-12-30 18:56:34讲友元之前先讲普通的成员函数的函数指针 <code class=sourceCode>class Std_interface { public: virtual void suspend() = 0; }; // define the pointer of function typedef void (Std_... -
关于C++友元函数的实现讲解
2021-01-21 18:45:40友元函数是一种特殊的函数,它必须要在类中进行声明,但其本身并不是类的成员函数,但友元函数可以访问类的私有成员变量。 友元函数的好处: 1、实现类之间的数据共享 2、提高程序运行效率,方便编程 友元函数的坏处... -
简要介绍C++编程中的友元函数和友元类
2021-01-20 06:13:09一个类中可以有 public、protected、private 三种属性的成员,通过对象可以访问 ...友元可以访问与其有好友关系的类中的私有成员,友元包括友元函数和友元类。如果您对友元这个名词不习惯,可以按原文 friend 理解为 -
C++中的friend友元函数详细解析
2020-09-05 00:10:29友元可以是一个函数,该函数被称为友元函数;友元也可以是一个类,该类被称为友元类。友元函数的特点是能够访问类中的私有成员的非成员函数。友元函数从语法上看,它与普通函数一样,即在定义上和调用上与普通函数... -
C++友元函数 普通函数声明为友元函数
2022-05-21 19:23:51友元函数 如果在本类以外的其他地方定义了一个函数(这个函数可以是不属于任何类的非成员函数,也可以是其他类的成员函数),在对本类进行声明时,在类体中用friend对该函数进行声明,此函数就称为本类的“友元...友元函数
如果在本类以外的其他地方定义了一个函数(这个函数可以是不属于任何类的非成员函数,也可以是其他类的成员函数),在对本类进行声明时,在类体中用friend对该函数进行声明,此函数就称为本类的“友元函数”。一个类的友元函数可以访问这个类中的私有成员。
例如,定义一个func()函数,在C++的TestA类中声明func()函数是当前类的“友元”函数,那么,这个func()函数就可以访问TestA类的私有成员。
2.1 普通函数声明为友元函数
我们可以定义一个普通的函数,希望这个函数能够访问一个类中的成员变量,那么,我们就在定义类的时候,声明这个函数是该类的友元函数,相当是说:在定义类的时候,把该普通函数声明为自己的一个朋友,允许这个朋友访问自己的成员变量。
这样,一个函数可以被多个类声明为“朋友”,它可以访问多个类中的成员变量。
通过下面的例子,可以理解友元函数的性质和作用。如下是一个友元函数的测试例子:
程序运行结果如下:
可以看到,在print()函数中可以引用stud对象的private私有成员。是因为,print()函数在student类中声明为友元。
请注意print()是一个在类外定义的函数,它不是属于student类的一个函数,所以,在定义的时候,并没有使用类前缀。它是非成员函数,不属于任何类。但是,我们把它声明为student类的一个“朋友”,让它可以访问student类的私有成员变量。
所以,使用 friend 关键字,在student类中声明定义在别处的print() 函数为student类的一个友元,这样,print() 是student类的朋友,就可以访问它的私有成员变量。
注意:在print() 中访问私有成员变量的时候,必须加上“对象名”,不能够如下:
void print(student& s)//定义友元函数
{
cout << "name = " << name << endl;
cout << "addr = " << addr << endl;
cout << "number = " << number << endl;
}
因为,print() 不是student类中的一个成员函数,它只是student类的一个朋友。不能够默认引用student类的成员变量,必须指定要访问的对象。
-
友元函数和友元类
2021-05-26 22:40:49友元有:友元函数,友元成员,友元类 友元可以放在类的公有,私有,保护部分。 友元函数 1.友元函数可访问类的私有和保护成员,但不是类的成员函数 2.友元函数不能用const修饰 3.友元函数可以在类定义的任何地方...友元的概念:
遵循一定规则而使对象以外的软件系统能够不经过消息方式而直接访对象内封装的数据成员的技术方法便是友元。
友元是面向对象系统与过程系统衔接纽带。友元有:友元函数,友元成员,友元类
友元可以放在类的公有,私有,保护部分。友元函数
1.友元函数可访问类的私有和保护成员,但不是类的成员函数
2.友元函数不能用const修饰
3.友元函数可以在类定义的任何地方声明,不受类访问限定符限制
4.一个函数可以是多个类的友元函数在类的定义中用friend声明了一个外部函数或其他类的成员函数(public和private均可)后,这个外部函数称为类的友元函数。
由干友元函数不是类的成员,所以没有this指针,访问该类的对象的成员时,必须使用对象名,而不能直接使用类的成员名。
虽然友元函数是在类中说明的,但其名字的作用域在类外,作用域的开始点在说明点、结束点和类名相同。因此,友元说明可以代替该函数的函数说明。#include <bits/stdc++.h> using namespace std; class Point { private: int x, y; friend float dis(Point &p1, Point &p2); //可以是public,也可是private public: Point(int i, int j) { //构造函数,带缺省参数值 x = i; y = j; } void disp() { cout << "(" << x << "," << y << ")"; } }; float dis(Point &p1, Point &p2) { //友元函数的实现 //友元函数中可访问类的private成员 float d = sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y)); return d; } int main() { Point p1(1, 2), p2(4, 5); //声明两个Point类的对象p1和p2 p1.disp(); //显示点p1的信息 cout << "与"; p2.disp(); //显示点p2的信息 cout << "距离=" << dis(p1, p2) << endl; //利用友元函数计算两点举例 return 0; }
友元类
友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员。
友元关系是单向的,不具有交换性。
友元关系不能传递->如果B是A的友元,C是B的友元,则不能说明C时A的友元。class Date; // 前置声明 class Time { friend class Date; // 声明日期类为时间类的友元类,则在日期类中就直接访问Time类中的私有成 员变量 public: Time(int hour, int minute, int second):_hour(hour) , _minute(minute) , _second(second) {} private: int _hour; int _minute; int _second; }; class Date { public: Date(int year = 1900, int month = 1, int day = 1): _year(year), _month(month) , _day(day) {} void SetTimeOfDate(int hour, int minute, int second) { // 直接访问时间类私有的成员变量 _t._hour = hour; _t._minute = minute; _t.second = second; } private: int _year; int _month; int _day; Time _t; };
#include <iostream> using namespace std; class Box { double width; public: friend void printWidth(Box box); friend class BigBox; void setWidth(double wid); }; class BigBox { public : void Print(int width, Box &box) { // BigBox是Box的友元类,它可以直接访问Box类的任何成员 box.setWidth(width); cout << "Width of box : " << box.width << endl; } }; // 成员函数定义 void Box::setWidth(double wid) { width = wid; } // 请注意:printWidth() 不是任何类的成员函数 void printWidth(Box box) { /* 因为 printWidth() 是 Box 的友元,它可以直接访问该类的任何成员 */ cout << "Width of box : " << box.width << endl; } // 程序的主函数 int main() { Box box; BigBox big; // 使用成员函数设置宽度 box.setWidth(10.0); // 使用友元函数输出宽度 printWidth(box); // 使用友元类中的方法设置宽度 big.Print(20, box); getchar(); return 0; }
友元成员
除了一般的函数可以作为某个类的友元外,另一个类的成员函数也可以作为某个类的友元。声明时需在友元成员函数前加上其所在的类名。定义友元成员的好处是两个类可以以某种方式相互合作、协调工作,完成某一任务。另一个类的成员函数可以作为某个类的友元,只是声名友元函数时要加上成员函数所在的类名,称为友元成员。
声名:
friend 函数返回类型 类名::成员函数名(形参列表)#include <iostream> using namespace std; class date; class time { public: time(int, int, int); void display(date &); private: int hour; int minute; int sec; }; class date { public: date(int, int, int); friend void time::display(date &); private: int month; int day; int year; }; time::time(int h, int m, int s) { hour = h; minute = m; sec = s; } void time::display(date &d) { cout << d.month << "." << d.day << "." << d.year << endl; cout << hour << ":" << minute << ":" << sec << endl; } date::date(int m, int d, int y) { month = m; day = d; year = y; } int main () { time t1(10, 51, 56); date d1(3, 20, 2018); t1.display(d1); return 0; }
-
c++模板友元函数 友元类
2015-04-11 01:38:36关于c+模板之友元类友元函数的实例化,图形界面之矩形。 -
关于C++中的友元函数的一些总结
2020-09-05 00:27:17以下是对C++中的友元函数进行了详细的总结介绍,需要的朋友可以过来参考下 -
C++运算符重载友元函数实例
2016-08-17 21:37:36一个实例,实现运算符重载(成员函数和非成员函数两种方式),友元函数的使用,注意事项等,自己学习时编写的, -
友元 基础详解版 (友元函数、友元类、友元非成员函数和友元成员函数)
2021-04-06 09:00:51如果在某个类的定义中用friend声明了一个外部函数(或者是其他类的成员函数,既可以是public型,也可以是private型)后,这个外部函数称为类的友元函数。 C++提供一种允许外部类和函数存取类的私有成员和保护成员的... -
友元函数代码实例
2015-05-19 19:56:54友元函数,类外普通函数声明为类的友元,之后即可与类共享数据 -
C++友元函数和友元类概念解析
2021-05-23 10:15:21一、友元函数友元函数是一种特殊的函数,它需要在类体内进行说明,可以访问类的私有成员和保护成员,但又不是类的成员函数。友元函数的说明如下:friend 数据类型函数名(参数)其中,friend是说明友元函数的关键字,... -
【C++】友元函数和友元类(作用及优缺点)
2020-11-06 16:22:15一、友元函数 二、友元类 三、友元的优缺点 一、友元函数 结合着类的特性,可知:类具有封装和信息隐藏的特性。只有类的成员函数才能访问类的私有成员,程序中的其他函数是无法访问私有成员的。非成员函数可以... -
C++友元函数与拷贝构造函数详解
2021-01-21 18:40:53一、友元函数 1.友元函数概述: (1)友元函数是定义在一个类外的普通函数。 友元函数和普通函数的定义一样;在类内必须将该普通函数声明为友元。 (2)友元函数不是成员函数。 不能通过对象来调用,而是直接调用;友元函数... -
【C++】友元函数,非成员函数作友元函数,成员函数作友元函数。
2020-07-31 18:41:41在c++中,经常会定义类。类有一个特点就是数据封装数据...使用友元函数将百分制学生的成绩转换成相应的分数等级。 #include<iostream> using namespace std; #include<iomanip> #include<string.h> -
友元函数
2018-09-03 10:27:37引入友元函数的原因 类具有封装、继承、多态、信息隐藏的特性,只有类的成员函数才可以访问类的私有成员,非成员函数只能访问类的公有成员。为了使类的非成员函数访问类的成员,唯一的做法就是将成员定义为public,... -
C++ 友元函数
2020-11-20 16:37:251.1为什么要使用友元函数 在实现类之间数据共享时,减少系统开销,提高效率。如果类A中的函数要访问类B中的成员(例如:智能指针类的实现),那么类A中该函数要是类B的友元函数。 具体来说:为了使其他类的成员函数... -
什么场景下会用到友元函数?
2017-10-11 07:56:42什么场景下会用到友元函数,友元函数的作用是什么,友元函数和普通成员函数又有怎样的区别?这都是C++当中的一些基本概念,掌握好了无论是维护项目还是做项目开发都大有裨益。本文主要浅谈一下C++中的友元函数,如有... -
C++程序设计 友元函数、友元类 友元函数和友元类.ppt
2020-09-16 07:26:34xxx xxxxx 目 录 页 xx C++语言程序设计 xxx xxxxx 目 录 页 C++语言程序设计 绪 论 大连理工大学出版社 地址大连市软件园路80号 E-mail : dutp@ URLhttp://www.dutp,cn 友元函数和友元类 友元函数和友元类 类具有...