实用C语言中friend友元函数详细解析

合集下载

friend 友元函数

friend 友元函数

friend 友元函数关于友元函数友元函数是指该函数对象的可访问性,可以被类的某些特定函数或特定类的所有函数访问,而不必声明这些函数为类的成员函数。

友元函数不属于任何类,只有在类的定义中显式地为他们指定友元权限,由于他们有独立于类的实体,所以可以提供一种可以直接访问类的成员而不必使用成员函数的方法。

友元函数的作用是把多个类的实现封装起来,而可以通过友元函数来访问类的不同部分。

友元函数也可以把一系列复杂的操作细分为一些更简单的步骤。

下面以一个例子来说明。

下面是一个定义结构体Cat的例子:struct Cat{string name;int age;void eat(string food);void sleep();};上面的示例中,Cat有name和age两个成员变量,以及eat和sleep两个成员函数。

我们可以通过eat和sleep来访问这个类的成员变量,但是如果我们需要在其他类中实现一些操作,比如比较两只猫的年龄,我们就需要定义一个友元函数来访问Cat类的age成员变量了:bool compareCats(Cat c1, Cat c2){return c1.age < c2.age;}在Cat类中添加上友元函数声明:struct Cat{string name;int age;friend bool compareCats(Cat c1, Cat c2);void eat(string food);void sleep();};当定义完Cat类,我们就可以在其他类的函数中使用compareCats函数来比较两只猫的年龄了。

这就是友元函数的作用,它可以让多个类的实现封装起来,从而使用友元函数把一系列复杂的操作细分为一些更简单的步骤。

另外,友元函数也可以被抽象为一个成员函数,以更加方便地使用它。

C 06《友元和常成员》

C  06《友元和常成员》

VC++第六次课 2004.3.17 《友元和常成员》一、友元1、友元函数,①在类中说明,②但不是该类的成员,③允许访问该类的对象的所有成员。

简称友元,关键字friend。

例子:┌──────────────────────────────────┐class Location {private:float X, Y;…………friend float distance(Location &, Location &);};float distance(Location &a, Location &b){float dx = a.X - b.X;float dy = a.Y - b.Y;return sqrt(dx*dx + dy*dy);}└──────────────────────────────────┘优点:①效率,省去调用类的成员函数的开销,②随时通过使用友元增加类的接口。

缺点:破坏了封装性2、友元成员除了自由函数可以说明为友元之外,成员函数也可以说明为另一个类的友元,但要先进行定义性说明。

例子:┌──────────────────────────────────┐class two; //先对two做引用性说明class one {private:int a;public:void func(two &);void func2(..)};class two { //two的定义性说明private:int b;friend void one::func(two &); //友元friend class one; //one是two的友元类};void one::func(two &r){a = r.b;}└──────────────────────────────────┘3、友元类将类one说明为类two的友元类,意味者类one的所有成员函数都是类two的友元函数。

C++友元函数和友元类(C++friend)详解

C++友元函数和友元类(C++friend)详解

C++友元函数和友元类(C++friend)详解私有成员只能在类的成员函数内部访问,如果想在别处访问对象的私有成员,只能通过类提供的接⼝(成员函数)间接地进⾏。

这固然能够带来数据隐藏的好处,利于将来程序的扩充,但也会增加程序书写的⿇烦。

是从结构化的C语⾔发展⽽来的,需要照顾结构化设计程序员的习惯,所以在对私有成员可访问范围的问题上不可限制太死。

C++ 设计者认为,如果有的程序员真的⾮常怕⿇烦,就是想在类的成员函数外部直接访问对象的私有成员,那还是做⼀点妥协以满⾜他们的愿望为好,这也算是眼前利益和长远利益的折中。

因此,C++ 就有了友元(friend)的概念。

打个⽐⽅,这相当于是说:朋友是值得信任的,所以可以对他们公开⼀些⾃⼰的隐私。

友元分为两种:友元函数和友元类。

友元函数在定义⼀个类的时候,可以把⼀些函数(包括全局函数和其他类的成员函数)声明为“友元”,这样那些函数就成为该类的友元函数,在友元函数内部就可以访问该类对象的私有成员了。

将全局函数声明为友元的写法如下:friend 返回值类型函数名(参数表);将其他类的成员函数声明为友元的写法如下:friend 返回值类型其他类的类名::成员函数名(参数表);但是,不能把其他类的私有成员函数声明为友元。

关于友元,看下⾯的程序⽰例。

1. #include<iostream>2. ug namespace std;3. class CCar; //提前声明CCar类,以便后⾯的CDriver类使⽤4. class CDriver5. {6. public:7. void ModifyCar(CCar* pCar); //改装汽车8. };9. class CCar10. {11. private:12. int price;13. friend int MostExpensiveCar(CCar cars[], int total); //声明友元14. friend void CDriver::ModifyCar(CCar* pCar); //声明友元15. };16. void CDriver::ModifyCar(CCar* pCar)17. {18. pCar->price += 1000; //汽车改装后价值增加19. }20. int MostExpensiveCar(CCar cars[], int total) //求最贵⽓车的价格21. {22. int tmpMax = -1;23. for (int i = 0; i<total; ++i)24. if (cars[i].price > tmpMax)25. tmpMax = cars[i].price;26. return tmpMax;27. }28. int main()29. {30. return 0;31. }这个程序只是为了展⽰友元的⽤法,所以 main 函数什么也不做。

C++中友元的实例详解

C++中友元的实例详解

C++中友元的实例详解C++中友元的实例详解尽管友元被授予从外部访问类的私有部分的权限,但他们并不与⾯向对象的编程思想相悖;相反他提⾼了公共接⼝的灵活性。

⼀、友元类友元声明可以位于公有、私有活保护部分、其所在位置⽆关紧要我直接贴出⼀个摘⾃< c++ primer plus >的例⼦来演⽰ c++ 友元类其中 Remote 为 Tv的友元类。

Tv.h#ifndef TV_H_#define TV_H_/*⼀个类电视 */class Tv{public:friend class Remote; //Remote类可以访问Tv Privite 的私有部分enum {off,on //开关};enum{MinVal,MaxVal=20 //⾳量};enum {Antena,Cable //使⽤的天线、还是电缆};enum{TV ,DVD //⼯作模式};Tv(int s = off, int mc = 125) :state(s), volume(5), maxchannel(mc),channel(5), mode(Cable), input(TV) {}void onoff() { state = (state == on) ? off : on; }bool ison()const { return state == on; }bool volup(); //增⼤声⾳bool voldown(); //减⼩声⾳void chanup(); //频道 +void chandown();//频道 -void set_mode() { mode = (mode == Antena) ? Cable : Antena; }void set_input() { input = (input == TV) ? DVD : TV; }void settings()const; //显⽰所有设置private:int state; // 开或者关int volume; // ⾳量int maxchannel; //最⼤int channel; //当前频道int mode; // ⼴播还是电缆int input; //Tv 或者 DVD};/*Remote 的定义(遥控器) */class Remote {private :int mode; // 控制 TV 或 DVDpublic:Remote(int m = Tv::TV) :mode(m) {}bool volup(Tv & t) { return t.volup(); }bool voldown(Tv & t) { return t.voldown(); }void onoff(Tv & t) { return t.onoff(); }void chanup(Tv & t) { return t.chanup(); }void chandown(Tv & t) { return t.chandown(); }void set_chan(Tv &t, int c) { t.channel = c; } //访问了Tv的私有成员void set_mode(Tv &t) { t.set_mode(); }void set_input(Tv &t) { t.set_input(); }};#endif // TV_H_Tv.cpp#include "stdafx.h"#include "Tv.h"#include <iostream>bool Tv::volup() {if (volume < MaxVal) {volume++;return true;}else {return false;}}bool Tv::voldown() {if (volume > MinVal) {volume--;return true;}else {return false;}}void Tv::chanup() {if (channel < maxchannel) channel++;else channel = 1;}void Tv::chandown() {if (channel > 1) channel--;else channel = maxchannel;}void Tv::settings() const {using std::cout;using std::endl;cout << "TV is " << (state == off ? "off" : "on") << endl;if (state == on) {cout << "Volume setting =" << volume << endl;cout << "Channel setting = " << channel << endl;cout << "Mode = " << (mode == Antena ? "antenna" : "cable") << endl; cout << "Input = " << (input == TV ? "TV" : "DVD") << endl;}}测试代码:#include "stdafx.h"#include "tv.h"#include <iostream>int main(){using std::cout;Tv s42;cout << "Initial settings for 42 \" Tv: \n";s42.settings();s42.onoff();s42.chanup();cout << " \n Adjusted settings for 42 \" Tv: \n";s42.chanup();cout << "\n Adjusted settings for 42 \" Tv: \n";s42.settings();Remote grey;grey.set_chan(s42, 10);grey.volup(s42);grey.volup(s42);cout << " \n s42 \" settings after using remote: \n";s42.settings();Tv s58(Tv::on);s58.set_mode();grey.set_chan(s58, 58);cout << " \n s58 \" setting: \n";s58.settings();system("pause");return 0;}运⾏结果:Initial settings for 42 " Tv:TV is offAdjusted settings for 42 " Tv:Adjusted settings for 42 " Tv:TV is onVolume setting =5Channel setting = 7Mode = cableInput = TVs42 " settings after using remote:TV is onVolume setting =7Channel setting = 10Mode = cableInput = TVs58 " setting:TV is onVolume setting =5Channel setting = 58Mode = antennaInput = TV请按任意键继续. . .上述代码中将Remote类设置成为了Tv类的友元类,但事实上我们看到:唯⼀访问Tv的成员的⽅法是void set_chan(Tv &t, int c) { t.channel = c; } ,因此它是唯⼀需要友元的⽅法。

C 中的FRIEND友元函数

C  中的FRIEND友元函数

C++中的friend友元函数(2011-03-2321:01:46)转载分类:C标签:friend友元教育友元函数是可以直接访问类的私有成员的非成员函数。

它是定义在类外的普通函数,它不属于任何类,但需要在类的定义中加以声明,声明时只需在友元的名称前加上关键字friend。

我们已知道类具有封装和信息隐藏的特性。

只有类的成员函数才能访问类的私有成员,程序中的其他函数是无法访问私有成员的。

非成员函数可以访问类中的公有成员,但是如果将数据成员都定义为公有的,这又破坏了隐藏的特性。

另外,应该看到在某些情况下,特别是在对某些成员函数多次调用时,由于参数传递,类型检查和安全性检查等都需要时间开销,而影响程序的运行效率。

为了解决上述问题,提出一种使用友元的方案。

友元是一种定义在类外部的普通函数,但它需要在类体内进行说明,为了与该类的成员函数加以区别,在说明时前面加以关键字friend。

友元不是成员函数,但是它可以访问类中的私有成员。

友元的作用在于提高程序的运行效率(即减少了类型检查和安全性检查等都需要的时间开销),但是,它破坏了类的封装性和隐藏性,使得非成员函数可以访问类的私有成员。

友元可以是一个函数,该函数被称为友元函数;友元也可以是一个类,该类被称为友元类。

友元函数的特点是能够访问类中的私有成员的非成员函数。

友元函数从语法上看,它与普通函数一样,即在定义上和调用上与普通函数一样。

#include"cmath"#include"iostream"using namespace std;class Point{public:Point(double xx,double yy){x=xx;y=yy;}void GetXY();friend double Distance(Point&a,Point&b);protected:private:double x,y;};void Point::GetXY(){//cout<<"("<<this->x<<","<<this->y<<")"<<endl;cout<<"("<<x<<","<<y<<")"<<endl;}double Distance(Point&a,Point&b){double length;length=sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));//它可以引用类中的私有成员return length;}int main(void){Point p1(3.0,4.0),p2(6.0,8.0);p1.GetXY();//成员函数的调用方法,通过使用对象来调用p2.GetXY();double d=Distance(p1,p2);//友元函数的调用方法,同普通函数的调用一样,不要像成员函数那样调用cout<<d<<endl;system("pause");return0;}说明:在该程序中的Point类中说明了一个友元函数Distance(),它在说明时前边加friend 关键字,标识它不是成员函数,而是友元函数。

什么是友元函数

什么是友元函数

什么是友元函数?
答:和继承一样,可以说子继承父,友元就是朋友,它不是类的组成部分,因此被称为直接函数调用。

友元函数不能隐式访问类成员,而必须将成员操作符用于作为参数传递的对象。

友元函数要在一个类体内说明,形式为:friend 类型名友元函数名(形参表);然后在类体外对友元函数进行定义,定义的格式和普通函数相同,但可以通过对象作为参数直接访问对象的私有成员;
友元函数说明如下:①.必须在类的说明中说明友元函数,说明时以关键字friend开头,后跟友元函数的函数原型,友元函数的说明可以出现在类的任何地方,包括在private和public 部分。

②注意友元函数不是类的成员函数,所以友元函数的实现和普通函数一样,在实现时不用”::”指示属于那个类,只有成员函数才使用”::”作用域符号。

③友元函数不能直接访问类的成员,只能访问对象成员。

④友元函数可以访问对象的私有成员,但普通函数不行;⑤调用友元函数时,在实际参数中需要指出要访问的对象!。

友元函数

友元函数友元函数友元函数是指某些虽然不是类成员却能够访问类的所有成员的函数。

类授予它的友元特别的访问权。

通常同一个开发者会出于技术和非技术的原因,控制类的友元和成员函数(否则当你想更新你的类时,还要征得其它部分的拥有者的同意)。

目录友元函数(friend)?友元函数要在一个类体内说明,形式为:友元函数(friend)?友元函数要在一个类体内说明,形式为:展开友元函数(friend)?定义格式(c++):friend <返回类型> <函数名> (<参数列表>);分清成员函数,非成员函数和友元函数成员函数和非成员函数最大的区别在于成员函数可以是虚拟的而非成员函数不行。

所以,如果有个函数必须进行动态绑定(见条款38),就要采用虚拟函数,而虚拟函数必定是某个类的成员函数。

关于这一点就这么简单。

如果函数不必是虚拟的,情况就稍微复杂一点。

(条款38: 决不要重新定义继承而来的缺省参数值)举例看下面表示有理数的一个类:class rational {public:rational(int numerator = 0, int denominator = 1);int numerator() const;int denominator() const;private:...};这是一个没有一点用处的类。

(用条款18的术语来说,接口的确最小,但远不够完整。

)所以,要对它增加加,减,乘等算术操作支持,但是,该用成员函数还是非成员函数,或者,非成员的友元函数来实现呢?当拿不定主意的时候,用面向对象的方法来考虑!有理数的乘法是和rational类相联系的,所以,写一个成员函数把这个操作包到类中。

class rational {public:...const rational operator*(const rational& rhs) const;};(如果你不明白为什么这个函数以这种方式声明——返回一个const值而取一个const的引用作为它的参数——参考条款21-23。

C语言第三章2


类模板使用方式: 类模板使用方式: Compare <int> cmp1(4,7); 在尖括号内指定实际的类型名,在进行编译时, 在尖括号内指定实际的类型名,在进行编译时,编译 系统就用int取代类模板中的类型参数 取代类模板中的类型参数。 系统就用 取代类模板中的类型参数。
类模板形式定义形式: 类模板形式定义形式: Template<class numtype> class Compare { public: Compare(numtype a,numtype b) {x=a;y=b;} numtype max() {return(x>y)?x:y;} numtype min() {return(x<y)?x:y;} private: numtype x,y; };
程序的Date类需要被前向引用,即先使用,后定义。 类需要被前向引用,即先使用,后定义。 程序的 类需要被前向引用 只包含类名,不包括类体。 只包含类名,不包括类体。 3、一个函数可以被多个类声明为“朋友”,这样可以引 、一个函数可以被多个类声明为“朋友” 用多个类中的私有数据。 用多个类中的私有数据。
关于友元的两点说明: 关于友元的两点说明: (1)友元的关系是单向的而不是双向的; )友元的关系是单向的而不是双向的; (2)友元的关ຫໍສະໝຸດ 不能传递。 )友元的关系不能传递。
3.11 类模板 函数模板:建立一个通用函数, 复习 函数模板:建立一个通用函数,其函数类型 和形参类型不具体指定, 和形参类型不具体指定,用一个虚拟的类型来代 表。 例: #include<iostream> using namespace std; template<typename T>;//模板声明,其中 为 模板声明, 模板声明 其中T为 类型参数 定义一个通用函数, T max(T a,T b,T c)//定义一个通用函数,用T作 定义一个通用函数 作 虚拟类型名 { if(b>a) a=b; if(c>a) a=c; return a; }

友元函数——精选推荐

友元函数
引⼊友元的原因
类的私有成员只能通过类的成员函数访问,有时候需要在类的外部访问类的私有成员。

在不放弃私有成员安全性的情况下,使得⼀个普通函数或者类的成员函数可以访问到封装于某⼀类中的信息。

友元是⼀扇通往私有成员的后门。

友元函数
可以是⾮成员函数,也可以是另⼀个类的成员函数,统称为成员函数。

友元函数不属于当前类的成员函数,⽽是独⽴于当前类的外部函数,但它可以访问该类的所有成员,包括私有成员,保护成员,和公有车成员。

C语言中friend友元函数详细解析

C语言中friend友元函数详细解析C语言中friend友元函数详细解析友元函数是可以直接访问类的私有成员的非成员函数。

它是定义在类外的普通函数,它不属于任何类,但需要在类的定义中加以声明,声明时只需在友元的名称前加上关键字friend。

我们已知道类具有封装和信息隐藏的特性。

只有类的成员函数才能访问类的私有成员,程序中的其他函数是无法访问私有成员的。

非成员函数可以访问类中的公有成员,但是如果将数据成员都定义为公有的,这又破坏了隐藏的特性。

另外,应该看到在某些情况下,特别是在对某些成员函数多次调用时,由于参数传递,类型检查和安全性检查等都需要时间开销,而影响程序的运行效率。

为了解决上述问题,提出一种使用友元的方案。

友元是一种定义在类外部的普通函数,但它需要在类体内进行说明,为了与该类的成员函数加以区别,在说明时前面加以关键字friend。

友元不是成员函数,但是它可以访问类中的私有成员。

友元的作用在于提高程序的运行效率(即减少了类型检查和安全性检查等都需要的时间开销),但是,它破坏了类的封装性和隐藏性,使得非成员函数可以访问类的私有成员。

友元可以是一个函数,该函数被称为友元函数;友元也可以是一个类,该类被称为友元类。

友元函数的特点是能够访问类中的私有成员的非成员函数。

友元函数从语法上看,它与普通函数一样,即在定义上和调用上与普通函数一样。

复制代码代码如下:#include "cmath"#include "iostream"using namespace std;class Point{public:Point(double xx,double yy){x=xx;y=yy;}void GetXY();friend double Distance(Point &a,Point &b);protected:private:double x,y;};void Point::GetXY(){//cout<<"("<x<<","<y<<")"<<endl;cout<<"("<<x<<","<<y<<")"<<endl;}double Distance(Point &a,Point &b){double length;length=sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); //它可以引用类中的私有成员return length;}int main(void){Point p1(3.0,4.0),p2(6.0,8.0);p1.GetXY(); //成员函数的调用方法,通过使用对象来调用p2.GetXY();double d = Distance(p1,p2); //友元函数的调用方法,同普通函数的调用一样,不要像成员函数那样调用cout<<d<<endl;system("pause");return 0;}说明:在该程序中的Point类中说明了一个友元函数Distance(),它在说明时前边加friend关键字,标识它不是成员函数,而是友元函数。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

C语言中friend友元函数详细解析
友元函数是可以直接访问类的私有成员的非成员函数。

它是定义在类外的普通函数,它不属于任何类,但需要在类的定义中加以声明,声明时只需在友元的名称前加上关键字friend。

我们已知道类具有封装和信息隐藏的特性。

只有类的成员函数才能访问类的私有成员,程序中的其他函数是无法访问私有成员的。

非成员函数可以访问类中的公有成员,但是如果将数据成员都定义为公有的,这又破坏了隐藏的特性。

另外,应该看到在某些情况下,特别是在对某些成员函数多次调用时,由于参数传递,类型检查和安全性检查等都需要时间开销,而影响程序的运行效率。

为了解决上述问题,提出一种使用友元的方案。

友元是一种定义在类外部的普通函数,但它需要在类体内进行说明,为了与该类的成员函数加以区别,在说明时前面加以关键字friend。

友元不是成员函数,但是它可以访问类中的私有成员。

友元的作用在于提高程序的运行效率(即减少了类型检查和安全性检查等都需要的时间开销),但是,它破坏了类的封装性和隐藏性,使得非成员函数可以访问类的私有成员。

友元可以是一个函数,该函数被称为友元函数;友元也可以是一个类,该类被称为友元类。

友元函数的特点是能够访问类中的私有成员的非成员函数。

友元函数从语法上看,它与普通函数一样,即在定义上和调用上
与普通函数一样。

复制代码代码如下:
#include cmath
#include iostream
using namespace std;
class Point
{
public:
Point(double xx,double yy)
{
x=xx;
y=yy;
}
void GetXY();
friend double Distance(Point a,Point b);
protected:
private:
double x,y;
};
void Point::GetXY()
{
//cout(x,y)endl;
cout(x,y)endl;
}
double Distance(Point a,Point b)
{
double length;
length=sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); //它可以引用类中的私有成员
return length;
}
int main(void)
{
Point p1(3.0,4.0),p2(6.0,8.0);
p1.GetXY(); //成员函数的调用方法,通过使用对象来调用
p2.GetXY();
double d = Distance(p1,p2); //友元函数的调用方法,同普通函数的调用一样,不要像成员函数那样调用
coutdendl;
system(pause);
return 0;
}
说明:在该程序中的Point类中说明了一个友元函数Distance(),它在说明时前边加friend关键字,标识它不是成员函
数,而是友元函数。

它的定义方法与普通函数定义一样,而不同于成员函数的定义,因为它不需要指出所属的类。

但是,它可以引用类中的私有成员,函数体中的a.x,b.x,a.y,b.y都是类的私有成员,它们是通过对象引用的。

在调用友元函数时,也是同普通函数的调用一样,不要像成员函数那样调用。

本例中,p1.Getxy()和p2.Getxy()这是成员函数的调用,要用对象来表示。

而Distance(p1, p2)是友元函数的调用,它直接调用,不需要对象表示,它的参数是对象。

(该程序的功能是已知两点坐标,求出两点的距离。

)
下面对上面的代码进行输入、输出流的重载:
复制代码代码如下:
#include
#include
using namespace std;
class Point
{
public:
Point(double xx,double yy)
{
x=xx;
y=yy;
}
void GetXY();
friend double Distance(Point a,Point b);
friend ostream operator (ostream a,Point b);
protected:
private:
double x,y;
};
// friend ostream operator(ostream o,A another);
ostream operator (ostream out,Point b) //在类中声明的时候,可以是ostream a,函数定义的时候也可以是ostream out {
out(b.x,b.y)endl;
return out;
}
void Point::GetXY()
{
//cout(x,y)endl;
//cout(x,y)endl;
cout*this;
}
double Distance(Point a,Point b)
{
double length;
length=sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); return length;
}
int main(void)
{
Point p1(3.0,4.0),p2(6.0,8.0);
p1.GetXY();
p2.GetXY();
double d = Distance(p1,p2);
coutdendl;
system(pause);
return 0;
}。

相关文档
最新文档