友元函数及友元类
- 格式:docx
- 大小:16.64 KB
- 文档页数:7
友元函数友元类及⽤法友元函数可以修改访问类内部的私有成员,友元函数的参数之⼀是类元素,类指针或者是类引⽤,意思是修改某个对象中的类私有成员(对象⼀般是访问不了类私有成员的).若F类是A类的友元类,那么F类的所有成员函数都是A类的友元函数,在F类⾥声明⼀个A类的对象a,在F类内部,这个对象a可以直接访问A类的私有成员.友员类通常设计为⼀种对数据操作或类之间传递消息的辅助类#include "iostream"using namespace std;class A1{public:A1(){a1 = 100;a2 = 200;}int getA1(){return this->a1;}//声明⼀个友元函数friend void setA1(A1 *p, int a1); //什么这个函数是这个类的好朋友protected:private:int a1;int a2;};void setA1(A1 *p, int a1){p->a1 = a1;}//friend 破坏了类的封装性。
//friend关键字是⼀个关系户//why ⽆奈之际 java class//java---》1.class==》class==>java类//java类的反射 sun jdk api//cc++ 1预编译gcc -E 2汇编 gcc -i 3编译gcc -c 3、链接ld ===》汇编代码//friend//应⽤场景。
//const关键字冒牌货c//register//typedef 混号王void main11(){A1 mya1;cout<<mya1.getA1()<<endl;setA1(&mya1, 300);cout<<mya1.getA1()<<endl;system("pause");}class A{//b是a的好朋友friend class B;public:void display(){cout<<x<<endl;}protected:private:int x;};class B{public:void setA(int x){Aobj.x = x;}void printA(){cout<<Aobj.x<<endl; }protected:private:A Aobj;};void main(){B b1;b1.setA(100);b1.printA();system("pause");}。
友元函数和友元类⼀个类中可以有 public、protected、private 三种属性的成员,通过对象可以访问 public 成员,只有本类中的函数可以访问本类的 private 成员。
在类的外部就没有办法访问类的private成员吗?不是的。
现在,我们来介绍⼀种例外情况——友元(friend)。
借助友元(friend),可以使得其他类中的成员函数以及全局范围内的函数访问当前类的 private 成员。
1、友元函数在当前类以外定义的、不属于当前类的函数也可以在类中声明,但要在前⾯加 friend 关键字,这样的函数称为友元函数。
友元函数可以是不属于任何类的⾮成员函数,也可以是其他类的成员函数。
友元函数可以访问当前类中的所有成员,包括public、protected和private属性的成员。
所以,可以说友元函数破坏了类的封装性。
定义⽅式:class A{private:int i;friend void FriendFun(A *ptr,int x);public:void MemberFun(int x);};...void FriendFun(A *ptr, int x){ptr->i = x;}void A::MemberFun(int x){i = x;}说明:1)友元函数在类中的位置与访问权限⽆关,即“friend void FriendFun(A *ptr,int x);”语句放在private或者public都没有影响;2)友元函数通过对象参数访问私有成员,即需要输⼊参数中需要有对象的指针。
下⾯看⼀个简单例⼦:#include <iostream>using namespace std;class TestFriend{public:TestFriend(int a,int b){this->a = a;this->b = b;}int get_a(){return this->a;}friend void modifyTest(TestFriend *pT,int a);private:int a;int b;};void modifyTest(TestFriend *pT,int a){pT->a = a;}int main() {TestFriend tf(1,2);cout << tf.get_a() << endl;modifyTest(&tf,4);cout << tf.get_a() << endl;return0;}modifyTest()是⼀个全局范围内的函数,它不属于任何类,它的作⽤是修改对象pT中的a值,在类TestFriend中a为私有成员,原则上不能通过对象访问,但是加⼊友元之后便可以访问。
友元函数和友元类的定义及使用C++实验报告实验名称友元函数和友元类的定义及使用实验目的理解对象与类的关系,掌握对象的创建和使用掌握构造函数、析构函数的概念及使用方法掌握内存的动态分配的概念和使用方法掌握对象数组和对象指针掌握函数调用中参数的传递掌握友元函数和友元类的定义及使用class 类名 {private:数据成员或成员函数protected:数据成员或成员函数public:数据成员或成员函数};实验内容有Distance类和Point类,将Distance类定义为Point类的友元类来实现计算两点之间距离实验代码// point.hclass Distance;class Point{public:Point(int xx=0,int yy=0){X=xx;Y=yy;}friend class Distance;private:int X,Y;};class Distance{public:float fDist(Point a,Point b);};//point.cpp#include"iostream"#include"math.h"using namespace std;#include"point.h"#include"math.h"int _tmain(int argc, _TCHAR* argv[]){Point myp1(1,1),myp2(4,5);Distance d;cout<<"The distance is: ";cout<<d.fdist(myp1,myp2)<<endl;< p=""> return 0;}float Distance::fDist(Point p1,Point p2) {double x,y;x=p1.X -p2.X ;y=p1.Y -p2.Y ;return float(sqrt(x*x+y*y));}心得体会通过本次试验,让我更加熟练运用了友元函数和友元类的定义及使用,加快了学习的进程,知识的掌握实验名称运算符重载实验目的理解为什么要进行运算符重载,在什么情况下进行运算符重载。
c友元函数和友元类用法详解C++中的友元函数和友元类是一种特殊的函数和类,它们可以访问类的私有成员变量和类的私有成员函数。
本文将详细介绍C++中友元函数和友元类的用法,以及在实际编程中应用友元函数和友元类所带来的优势。
首先,让我们来了解一下C++中什么是友元函数和友元类。
友元函数是一种特殊的函数,它允许外部函数访问类的私有成员变量和私有成员函数,而不需要对类进行任何修改。
友元函数还可以在类外定义,以便更加方便地使用它来访问类的私有成员变量和私有成员函数。
友元类是一种特殊的类,它允许一个类的私有成员函数访问另一个类的私有成员函数和私有成员变量,而不需要对类进行任何修改。
友元类也可以定义在类外,但其功能与友元函数不同,友元类可以访问另一个类的整个实例,而友元函数只能访问另一个类的私有成员变量和私有成员函数。
定义友元函数和友元类的用法其实非常简单,我们只需要在类的声明中使用关键字“friend”来指定友元的函数或类就可以了: class A {private:int a;public:void setA (int a);friend void foo (A& A); //友元函数};class B {private:int b;public:void setB (int b);friend class C; //友元类};以上的代码定义了两个类:A类和B类,其中A类定义了一个友元函数foo,而B类定义了一个友元类C。
定义完友元函数和友元类之后,就可以使用它们来访问类的私有成员变量和私有成员函数了。
在实际使用中,友元函数和友元类有着诸多的优势,比如可以更加方便的封装类的私有成员,以及更加方便的实现代码的重构。
首先,友元函数和友元类可以帮助我们更好地封装类的私有成员,使类的私有成员不能被外部类访问。
同时,可以使用友元函数和友元类来实现类的重构,这样可以更加方便地实现代码的复用,让程序更加简洁和易读。
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 函数什么也不做。
41、友元函数和友元类友元提供了不同类的成员函数之间、类的成员函数和一般函数之间进行数据共享的机制。
通过友元,一个不同函数或者另一个类中的成员函数可以访问类中的私有成员和保护成员。
友元的正确使用能提高程序的运行效率,但同时也破坏了类的封装性和数据的隐藏性,导致程序可维护性变差。
1)友元函数有元函数是可以访问类的私有成员的非成员函数。
它是定义在类外的普通函数,不属于任何类,但是需要在类的定义中加以声明。
friend 类型函数名(形式参数);一个函数可以是多个类的友元函数,只需要在各个类中分别声明。
2)友元类友元类的所有成员函数都是另一个类的友元函数,都可以访问另一个类中的隐藏信息(包括私有成员和保护成员)。
friend class 类名;使用友元类时注意:(1) 友元关系不能被继承。
(2) 友元关系是单向的,不具有交换性。
若类B是类A的友元,类A不一定是类B的友元,要看在类中是否有相应的声明。
(3) 友元关系不具有传递性。
若类B是类A的友元,类C是B的友元,类C不一定是类A的友元,同样要看类中是否有相应的申明41、友元函数和友元类友元提供了不同类的成员函数之间、类的成员函数和一般函数之间进行数据共享的机制。
通过友元,一个不同函数或者另一个类中的成员函数可以访问类中的私有成员和保护成员。
友元的正确使用能提高程序的运行效率,但同时也破坏了类的封装性和数据的隐藏性,导致程序可维护性变差。
1)友元函数有元函数是可以访问类的私有成员的非成员函数。
它是定义在类外的普通函数,不属于任何类,但是需要在类的定义中加以声明。
friend 类型函数名(形式参数);一个函数可以是多个类的友元函数,只需要在各个类中分别声明。
2)友元类友元类的所有成员函数都是另一个类的友元函数,都可以访问另一个类中的隐藏信息(包括私有成员和保护成员)。
friend class 类名;使用友元类时注意:(1) 友元关系不能被继承。
(2) 友元关系是单向的,不具有交换性。
友元关系式摘要:1.友元关系的定义与作用2.友元关系的分类3.友元关系的声明与使用4.友元关系的注意事项正文:一、友元关系的定义与作用友元关系是C++中用于实现类与类之间的一种互助关系,它允许一个类的成员函数或者整个类访问另一个类的私有成员和保护成员。
这种关系为类的设计者提供了一种在类之间共享数据和功能的灵活方式,同时又保证了数据的封装性和安全性。
二、友元关系的分类友元关系可以分为两类:友元函数和友元类。
1.友元函数:友元函数是在一个类中声明的,可以访问另一个类的所有成员。
友元函数通常用于解决函数与类之间的耦合问题,使得函数可以更好地复用。
2.友元类:友元类是在一个类中声明的,可以访问另一个类的所有成员和友元函数。
友元类可以访问另一个类的所有内容,包括私有成员、保护成员和公有成员,使得类的设计更加灵活。
三、友元关系的声明与使用1.友元关系的声明:在类中使用关键字friend 声明友元关系。
友元关系的声明分为友元函数和友元类。
- 友元函数声明:friend 返回类型类名::成员函数名(参数列表);- 友元类声明:friend class 类名;2.友元关系的使用:在声明了友元关系的类中,可以直接访问另一个类的成员和函数,无需使用访问修饰符。
四、友元关系的注意事项1.友元关系是一种“双刃剑”,它虽然为类的设计提供了便利,但同时也破坏了封装性。
因此,在实际编程中,应谨慎使用友元关系,避免过度暴露类的实现细节。
2.友元关系并不能代替继承关系。
友元关系主要用于解决功能复用和类间数据共享的问题,而继承关系主要用于实现类的层次结构和代码重用。
在实际编程中,应根据需求选择合适的关系。
3.在使用友元关系时,要注意避免出现死循环。
当两个或多个类互相声明为友元类时,可能会导致死循环,使得程序无法正常编译和运行。
C++运算符重载三种形式(成员函数,友元函数,普通函数)详解三种重载⽅式⾸先,介绍三种重载⽅式:1//作为成员函数重载(常见)2class Person{3 Private:4string name;5int age;6public:7 Person(const char* name, int age):name(name),age(age){}8bool operator<(const Person& b);910 };11bool Person::operator<(const Person& b)12 {13//作为成员函数时,*this即为左操作数a14 ...15 }1//作为友元函数重载2class Person{3private:4string name;5int age;6public:7 Person(const char* name, int age):name(name),age(age){}8 friend bool operator<(const Person& a,const Person& b);910 };11bool operator<(const Person& a,const Person& b)12 {13 ...14 }1//作为普通函数重载(不推荐)2class Person{3public://注意,重载运算符为普通函数时,使⽤到的类成员必须为public4string name;5int age;6public:7 Person(const char* name, int age):name(name),age(age){}89 };10bool operator<(const Person& a,const Person& b)11 {12 ...13 }作为成员函数重载先介绍第⼀种:bool Person::operator<(const Person& b),bool是函数返回类型,Person::只是指定了成员函数所属类名。
友元类的定义和⽤法
1.概述
①友元:是定义⼀个类是,该主动声明哪些其他类或函数是它的朋友,进⽽给他们定向提供对类的访问特权。
②友元是C++提供的⼀种破坏数据封装和数据隐藏的机制。
③通过友元将⼀个模块声明为另⼀个模块的友元,⼀个模块能够引⽤到另⼀个模块中本是被隐藏的信息。
④可以使⽤友元函数和友元类。
建议:为了确保数据完整性,及数据封装与隐藏原则,建议尽量不使⽤或少使⽤。
2、友元函数
①友元函数是在类的声明中由关键字friend修饰说明的⾮成员函数,在它的函数体中能通过对象名访问 private和protected 成员。
②作⽤:增加灵活性,使程序员可以在封装和快速性⽅⾯做合理选择。
③访问对象中的成员必须通过对象名。
④友元是单向的。
友元函数的定义⽅法(以定义⼀个Point类为例)
(该函数传⼊引⽤,节约⼯耗)
此时,就会遇到在函数中改变对象私有信息的危险,破坏数据的封装。
例如:
输出:
对⽐原先的输出:
如果想防⽌对象的私有数据被更改 , 可以在传⼊引⽤时加 const修饰例如:
这样在函数中再想更改对象的私有数据时就会报错,例如:
⾄于const的⽤法相信⼤家都见过了,在后⾯的博客中会加以补充。
友元函数及友元类已有 20621 次阅读 2009-5-9 15:43 |个人分类:C/C++什么是友元(friend)?允许另一个类或函数访问你的类的东西。
友元可以是函数或者是其他的类。
类授予它的友元特别的访问权。
通常同一个开发者会出于技术和非技术的原因,控制类的友元和成员函数(否则当你想更新你的类时,还要征得其它部分的拥有者的同意)。
分清成员函数,非成员函数和友元函数成员函数和非成员函数最大的区别在于成员函数可以是虚拟的而非成员函数不行。
所以,如果有个函数必须进行动态绑定,就要采用虚拟函数,而虚拟函数必定是某个类的成员函数。
关于这一点就这么简单。
如果函数不必是虚拟的,情况就稍微复杂一点。
Ø类的主要特点之一是数据隐藏,即类的私有成员只能在类定义的范围内使用,也就是说私有成员只能通过它的成员函数来访问。
Ø但是,有时候需要在类的外部访问类的私有成员。
为此,就需要寻找一种途径,在不放弃私有数据安全性的情况下,使得类外部的函数或类能够访问类中的私有成员,在C++中就用友元作为实现这个要求的辅助手段。
ØC++中的友元为数据隐藏这堵不透明的墙开了一个小孔,外界可通过这个小孔窥视类内部的秘密,友元是一扇通向私有成员的后门。
Ø友元可分为:友元函数,友元成员,友元类。
Ø友元函数不是当前类的成员函数,而是独立于当前类的外部函数,但它可以访问该类的所有对象的成员,包括私有成员和公有成员。
Ø在类定义中声明友元函数时,需在其函数名前加上关键字friend。
此声明可以放在公有部分,也可以放在私有部分。
友元函数可以定义在类的内部,也可以定义在类的外部。
1.友元函数虽然可以访问类对象的私有成员,但它毕竟不是成员函数。
因此,在类的外部定义友元函数时,不必像成员函数那样,在函数名前加上“类名::”。
2.友元函数一般带有一个该类的入口参数。
因为友元函数不是类的成员,所以它不能直接引用对象成员的名称,也不能通过this指针引用对象的成员,它必须通过作为入口参数传递进来的对象名或对象指针来引用该对象的成员。
3.当一个函数需要访问多个类时,友元函数非常有用,普通的成员函数只能访问其所属的类,但是多个类的友元函数能够访问相应的所有类的数据。
例程序2使用一个友元函数访问两个不同的类4.友元函数通过直接访问对象的私有成员,提高了程序运行的效率。
在某些情况下,如运算符被重载时,需要用到友元。
但是友元函数破坏了数据的隐蔽性,降低了程序的可维护性,这与面向对象的程序设计思想是背道而驰的,因此使用友元函数应谨慎。
Ø除了一般的函数可以作为某个类的友元外,一个类的成员函数也可以作为另一个类的友元,这种成员函数不仅可以访问自己所在类对象中的私有成员和公有成员,还可以访问friend声明语句所在类对象中的私有成员和公有成员,这样能使两个类相互合作、协调工作,完成某一任务。
Ø例程序3使用友元成员函数访问另一个类说明:1.一个类的成员函数作为另一个类的友元函数时,必须先定义这个类。
例如上例中,类boy的成员函数为类girl的友元函数,必须先定义类boy。
并且在声明友元函数时,要加上成员函数所在类的类名,如:friend void boy::disp(girl &);2.程序中还要使用“向前引用”,因为函数disp()中将girl &作为参数,而girl要晚一些时候才定义。
Ø不仅函数可以作为一个类的友元,一个类也可以作为另一个类的友元。
这种友元类的说明方法是在另一个类声明中加入语句“friend 类名;”,其中的“类名”即为友元类的类名。
此语句可以放在公有部分也可以放在私有部分,例如:class Y{//……};class X{//……friend Y;//……};Ø当一个类被说明为另一个类的友元时,它的所有的成员函数都成为另一个类的友元函数,这就意味着为友元的类中的所有成员函数都可以访问另一个类的私有成员。
例程序4友元类说明:1.友元关系是单向的,不具有交换性(我是你的朋友,不能推断出:你是我的朋友)。
2.友元关系也不具有传递性(我是你的朋友,你是他的朋友,不能推断出:我是他的朋友)。
通过下面几个程序我们来了解一下友元函数程序1 使用友元函数#include <iostream.h>#include <string.h>class girl{private:char *name;int age;public:girl(char *n,int d){ name=new char[strlen(n)+1];strcpy(name,n);age=d;}friend void disp(girl &); //声明为友元函数~girl(){delete name;}};void disp(girl &x) //定义友元函数{cout<<"girl\'s nameis:"<<<<",age:"<<x.age<<endl;}void main(){girl e("Chen Xingwei",18);disp(e); //调用友元函数}程序2使用一个友元函数访问两个不同的类#include <iostream.h>#include <string.h>class boy; //向前引用class girl{char name[25];int age;public:void init(char N[],int A);friend void prdata(const girl plg,const boy plb); //声明函数为girl 类的友元函数};void girl::init(char N[],int A){ strcpy(name,N);age=A;}class boy{char name[25];int age;public:void init(char N[],int A);friend void prdata(const girl plg,const boy plb); //声明函数为boy类的友元函数};void boy::init(char N[],int A){ strcpy(name,N);age=A;}void prdata(const girl plg,const boy plb){cout<<"女孩"<<<<','<<plg.age<<"岁;";cout<<"男孩"<<<<','<<plb.age<<"岁。
\n";}void main(){ girl G1,G2,G3;boy B1,B2,B3;G1.init("Stacy",12);G2.init("Judith",13);G3.init("Leah",12);B1.init("Jim",11);B2.init("Micheal",13);B3.init("Larry",12);prdata(G1,B1);prdata(G2,B2);prdata(G3,B3);}程序3使用友元成员函数访问另一个类#include <iostream.h>#include <string.h>class girl; //向前引用class boy{char *name;int age;public:boy(char *N,int A){ name=new char[strlen(N)+1];strcpy(name,N);age=A;}void disp(girl &); //声明disp()为类boy的成员函数~boy(){delete name;}};class girl{char *name;int age;public:girl(char *N,int A){ name=new char[strlen(N)+1];strcpy(name,N);age=A;}friend void boy::disp(girl &); //声明类boy的成员函数disp()为类girl 的友元函数~girl(){delete name;}};void boy::disp(girl &x){cout<<"boy\'s nameis:"<<name<<",age:"<<age<<endl; //访问本类对象成员cout<<"girl\'s nameis:"<<<<",age:"<<x.age<<endl; //访问友元类对象成员}void main(){ boy b("chen hao",25);girl g("zhang wei",18);b.disp(g);}友元类程序4 boy为girl的友元类#include <iostream.h>#include <string.h>class girl;class boy{char *name;int age;public:boy(char *n,int d){ name=new char[strlen(n)+1];strcpy(name,n);age=d;}void disp(girl &); //声明disp()为类boy的成员函数~boy(){delete name;}};class girl{char *name;int age;friend boy; //声明类boy是类girl的友元public:girl(char *n,int d){ name=new char[strlen(n)+1];strcpy(name,n);age=d;}~girl(){delete name;}};void boy::disp(girl &x) //定义函数disp()为类boy的成员函数,也是类girl 的友元函数{ cout<<;"boy\'s name is:"<<name<<",age:"<<age<<endl; cout<<"girl\'s nameis:"<<<<",age:"<<x.age<<endl;}void main(){ boy b("chen hao",25);girl g("zhang wei",18);b.disp(g);}。