简单的网站怎样做,网站首页策划怎么做,建e网手机版,网站备案承若怎么写C中的友元机制允许类的非公有成员被一个类或者函数访问#xff0c;友元按类型分为三种#xff1a;普通非类成员函数作为友元,类的成员函数作为友元#xff0c;类作为友元。友元包括友元的声明以及友元的定义。
友元的声明默认为了extern#xff0c;就是说友元类或者友元函数…C中的友元机制允许类的非公有成员被一个类或者函数访问友元按类型分为三种普通非类成员函数作为友元,类的成员函数作为友元类作为友元。友元包括友元的声明以及友元的定义。
友元的声明默认为了extern就是说友元类或者友元函数的作用域已经扩展到了包含该类定义的作用域所以即便我们在类的内部定义友元函数也是没有关系的。
友元可以是一个函数该函数被称为友元函数友元也可以是一个类该类被称为友元类。
友元函数的特点是能够访问类中的私有成员的非成员函数。
友元函数从语法上看它与普通函数一样即在定义上和调用上与普通函数一样。
友元函数的实现可以在类外定义但必须在类内部声明
友元函数是可以直接访问类的私有成员的非成员函数。它是定义在类外的普通函数它不属于任何类
但需要在类的定义中加以声明声明时只需在友元的名称前加上关键字friend。我们已知道类具有封装和信息隐藏的特性。只有类的成员函数才能访问类的私有成员程序中的其他函数是无法访问私有成员的。非成员函数可以访问类中的公有成员但是如果将数据成员都定义为公有的这又破坏了隐藏的特性。另外应该看到在某些情况下特别是在对某些成员函数多次调用时由于参数传递类型检查和安全性检查等都需要时间开销而影响程序的运行效率。
为了解决上述问题提出一种使用友元的方案。友元是一种定义在类外部的普通函数但它需要在类体内进行说明为了与该类的成员函数加以区别在说明时前面加以关键字friend。友元不是成员函数但是它可以访问类中的私有成员。友元的作用在于提高程序的运行效率即减少了类型检查和安全性检查等都需要的时间开销但是它破坏了类的封装性和隐藏性使得非成员函数可以访问类的私有成员。
【友元函数非类成员函数却访问类私有成员】
1.普通的非成员函数友元[cpp] view plaincopy#include cmath #include iostream using namespace std; class Point { public: Point(double xx,double yy) { xxx; yyy; } 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; lengthsqrt((a.x-b.x)*(a.x-b.x)(a.y-b.y)*(a.y-b.y)); //a.xb.xa.yb.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.xb.xa.yb.y都是类的私有成员它们是通过对象引用的。在调用友元函数时也是同普通函数的调用一样不要像成员函数那样调用。本例中p1.Getxy()和p2.Getxy()这是成员函数的调用要用对象来表示。而Distance(p1, p2)是友元函数的调用它直接调用不需要对象表示它的参数是对象。(该程序的功能是已知两点坐标求出两点的距离。)下面对上面的代码进行输入、输出流的重载
[cpp] view plaincopy#include cmath #include iostream using namespace std; class Point { public: Point(double xx,double yy) { xxx; yyy; } 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(this-x,this-y)endl; //cout(x,y)endl; cout*this; } double Distance(Point a,Point b) { double length; lengthsqrt((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; } 2.类作为友元
类作为友元需要注意的是友元类和原始类之间的相互依赖关系如果在友元类中定义的函数使用到了原始类的私有变量那么就需要在友元类定义的文件中包含原始类定义的头文件。但是在原始类的定义中包含友元类声明的那个类就不需要包含友元类的头文件.另外不需要在类定义前去声明友元类因为友元类的声明自身就是一种声明。[cpp] view plaincopy//A.h #pragma once #include iostream using namespace std; class A { //friend class B; //如果不写这句话将会出现编译错误 public: ~A(void); A(); private: int m_nItem; }; //A.cpp #include A.h A::A() { m_nItem 3; } A::~A(void) { } //B.h #pragma once class B { public: B(void); ~B(void); int func(); }; //B.cpp #include StdAfx.h #include B.h #include A.h //must include A.h #include iostream B::B(void) { } B::~B(void) { } int B::func() { coutThis is in Bendl; A a; return a.m_nItem; } 3.类成员函数作为友元函数
这个稍微有点复杂因为你要类成员函数作为友元你在声明友元的时候要用类限定符所以必须先定义包含友元函数的类但是在定义友元的函数时候又必须事先定义原始类。通常的做法先定义包含友元函数的类再定义原始类这个顺序不能乱。(如果是友元类则没有这种这种必须)如下面所示
[cpp] view plaincopy//A.h #pragma once #include B.h class A { friend int B::func(A xx); public: A(void):mx(20),my(30){} ~A(void){} private: int mx; int my; }; [cpp] view plaincopy//B.h #pragma once class A; class B { public: B(void); ~B(void); int func(A xx); }; [cpp] view plaincopy//B.cpp #include B.h #include A.h B::B(void) { } B::~B(void) { } int B::func(A xx) { return xx.mx * xx.my; } [cpp] view plaincopy//main.cpp #include A.h #include B.h #include iostream using namespace std; void main() { A a; B b; coutb.func(a)endl; system(pause); } 4. 友元不具有相互性只具有单项性若类B是类A的友元类A不一定是类B的友元要看在类中是否有相应的声明。
5. 友元不能被继承
B是A的友元类C是B的子类推不出C是A的友元
6. 友元不具有传递性
B是A的友元C是B的友元推不出C是A的友元
7. 友元函数的使用技巧
在用C实现单例模式时可以利用友元函数实例化对象。然后把类的构造函数和析构函数都设计成私有函数。[cpp] view plaincopyclass CMySingleton { public: friend CMySingleton InstanceMEC(); private: CMySingleton() {}; CMySingleton(const CMySingleton lxSington) {}; ~CMySingleton(){}; }; CMySingleton InstanceMEC() { //因为函数InstanceMEC()是类ClxSingletonMEC的友元函数所以可以访问类所有的成员函数.所以不会有编译错误 static CMySingleton Instance; return Instance; }