C++友元函数讲解
- 格式:ppt
- 大小:75.00 KB
- 文档页数:11
友元TAG:面向对象程序设计,面向对象的语言实现C++,友元TEXT:有时两个类或一个函数与某个类之间的关系十分密切,为了程序运行效率着想,希望这个函数和类可以像另一个类的成员一样无限制地存取它的所有成员,同时还希望在形式上尽量保持类的独立性和封装性。
为了解决这类问题,C++提供了友元的概念,一个类的友元可以存取这个类的所有成员,包括私有成员。
友元一般分为两种一一友元函数和友元类。
REF:.txt,友元函数.txt,友元类.txt友元函数TAG:面向对象程序设计,面向对象的语言实现C++,友元,友元函数TEXT:在类中可以将另一个函数声明为这个类的友元,这时,虽然这个函数可能是位于另一个文件中的外部函数或属于另一个类的成员函数,但它却具有了访问本类所有成员的权限,如同是本类的一个成员一样。
说明友元函数的方法如下。
[例2] 友元函数的说明示例。
#include "iostream.h"#include "math.h"class CPoint{private:double m_x;double m_y;public:CPoint(double x,double y){m_x=x;m_y=y;}double GetX(){ return m_x;}double GetY(){ return m_y; }friend double GetDistance(CPoint&a, CPoint&b);};double GetDistance(CPoint &a,CPoint &b){double x_increament=a.m_x- b.m_x;double y_increament=a.m_y- b.m_y;return sqrt(x_increament*x_increament+y_increament*y_increament)}void main(){CPoin pt1(3,5),pt2(6,8);cout<<"The distance is"<<GetDistance(pt1,pt2)<<endl;}上面程序中的函数GetDistance()被说明为类CPoint类的友元函数,因为计算两个点之间距离这个函数很常用,而这个丽数显然同类CPoint有着密切的联系。
C++中成员函数和友元函数的使⽤及区别详解为什么使⽤成员函数和友元函数这个问题⾄关重要,直接影响着后⾯的理解:程序数据:数据是程序的信息,会受到程序函数的影响。
封装是⾯向对象编程中的把数据和操作数据的函数绑定在⼀起的⼀个概念,这样能避免受到外界的⼲扰和误⽤,从⽽确保了安全。
数据封装引申出了另⼀个重要的 OOP 概念,即数据隐藏。
数据封装是⼀种把数据和操作数据的函数捆绑在⼀起的机制,数据抽象是⼀种仅向⽤户暴露接⼝⽽把具体的实现细节隐藏起来的机制。
C++ 通过创建类来⽀持封装和数据隐藏(public、protected、private)。
我们已经知道,类包含私有成员(private)、保护成员(protected)和公有成员(public)成员。
默认情况下,在类中定义的所有项⽬都是私有的。
由于C++的封装和隐藏特性,只有类定义的成员函数可以访问类定义的私有数据。
成员函数是数据封装和数据隐藏的机制。
友元是C++提供的⼀种破坏数据封装和数据隐藏的机制。
成员函数的使⽤⾸先先看代码class Stock{ //class declarationprivate:std:: string company;long shares;double share_val;double total_val;void set_tot(){ total_val=shares* share_val;}public:void acquire(const std:: string & co, long n, double pr);void buy(long num, double price);void se11(long num, double price);void update(double price);void show();};//note semicolon at the end注意这⾥⾯的private可以不写,如果不写的话默认是私有的。
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++中的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)?友元函数要在一个类体内说明,形式为:展开友元函数(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++运算符重载三种形式(成员函数,友元函数,普通函数)详解三种重载⽅式⾸先,介绍三种重载⽅式: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::只是指定了成员函数所属类名。