C++友元

</pre></p><pre name="code" class="cpp">

友元有友元类,友元成员函数,友元函数三种。

1、什么是友元?

官方解释:允许一个类将对其非公有成员的访问权授予指定的类或函数(分别是友元类和C++友元函数)。

自己解释:①友元从“友”字看出这个关系,友元类就是A类是B类的朋友,B类就充分了解A类,所以能访问A类中的成员变量与成员函数(B类若跟A类没关系,这样原本是不可以的,C++为了保护数据,隐藏细节,连返回类中的数据成员都要封装成一个函数,就是怕你直接访问内部数据乱搞,当然直接访问也是可以的,只是一般不这么做!现在B成了A的朋友,所以B能直接访问A)。注意,指定了A是B的朋友,不代表B是A的朋友,也就是说B的情况A是不了解的(生活就是这么现实!!)②友元成员函数,跟友元类相比,可访问范围变小了。我们指定的是A中的某个成员函数是B类的朋友,所以B类就能访问A类的所指定的成员函数(包括私有权限的成员函数)。③友元函数,这个从字面上看没有任何跟类有关的字眼(既不是类,也不是成员),它是类的非成员函数!这个非成员函数其实就是学C语言的时候所定义过的函数,总之就不是类里的。而同样加上了友元的字眼,这个函数就能访问它所指定的类的私有数据。具体怎么指定,请往下看!


2、如何使用友元?

使用关键字 friend,就可以到处找好基友了~~~

示例1、使用友元类

//----mytime.h
#ifndef MYTIME_H_
#define MYTIME_H_
class MyTime
{
<span>	</span>//friend void Remote::setTime(MyTime &otime,MyTime &ntime);<span>	</span>//使用友元成员函数
<span>	</span>
<span>	</span>friend class Remote;<span>						</span>//使用友元类
<span>	</span>private:
<span>	</span>int hours;
<span>	</span>int minutes;
<span>	</span>int seconds;
<span>	</span>public:
<span>	</span>MyTime (int h=0,int m=0,int s=0){hours=h;minutes=m;seconds=s;};
<span>	</span>MyTime (MyTime &time) {hours=time.hours;minutes=time.minutes;seconds=time.seconds;};
<span>	</span>~MyTime(){};
<span>	</span>
//<span>	</span>bool setTime(int h,int m,int s){hours=h;minutes=m;seconds=s;};
<span>	</span>void showtime(){std::cout<<"hours : "<<hours<<"minutes : "<<minutes << std::endl;};
<span>	</span>
<span>	</span>MyTime operator *(const int &t) const;


<span>	</span>friend MyTime operator *(int k,const MyTime &t);<span>	</span>//使用友元函数<span>			</span>
};
class Remote<span>	</span>//遥控类,可以设置时间
{
<span>	</span>public:<span>			</span>//构造函数一定要在前面加public 否则默认都是private
<span>	</span>Remote (int m){i=m;};<span>		</span>
<span>	</span>~Remote(){};
<span>	</span>void setTime(MyTime &otime,MyTime &ntime){ntime.hours=otime.hours;ntime.minutes=otime.minutes;ntime.seconds=otime.seconds;};
<span>	</span>private:
<span>	</span>int i;
};
MyTime MyTime::operator *(const int &t) const
{
<span>	</span>MyTime result;
<span>	</span>long totalminutes = hours*t*60+minutes*t;
<span>	</span>result.hours = totalminutes/60;
<span>	</span>result.minutes = totalminutes%60;
<span>	</span>return result;
}
MyTime operator *(int k,const MyTime &t)
{
<span>	</span>return t*k;
}


#endif
</pre><p></p><div>示例2、使用友元成员函数:</div><p></p><p></p><pre name="code" class="cpp"><pre name="code" class="cpp">
//----mytime.h
#ifndef MYTIME_H_
#define MYTIME_H_
class MyTime;<span style="white-space:pre">		</span>//前置声明
class Remote<span>	</span>//遥控类,可以设置时间
{
<span>	</span>public:<span>			</span>//构造函数一定要在前面加public 否则默认都是private
<span>	</span>Remote (int m){i=m;};<span>		</span>
<span>	</span>~Remote(){};
<span>	</span>void setTime(MyTime &otime,MyTime &ntime);
<span>	</span>private:
<span>	</span>int i;
};
class MyTime
{
<span>	</span>friend void Remote::setTime(MyTime &otime,MyTime &ntime);<span>	</span>//使用友元成员函数
<span>	</span>
<span>	</span>//friend class Remote;
<span>	</span>private:
<span>	</span>int hours;
<span>	</span>int minutes;
<span>	</span>int seconds;
<span>	</span>public:
<span>	</span>MyTime (int h=0,int m=0,int s=0){hours=h;minutes=m;seconds=s;};
<span>	</span>MyTime (MyTime &time) {hours=time.hours;minutes=time.minutes;seconds=time.seconds;};
<span>	</span>~MyTime(){};
<span>	</span>
//<span>	</span>bool setTime(int h,int m,int s){hours=h;minutes=m;seconds=s;};
<span>	</span>void showtime(){std::cout<<"hours : "<<hours<<"minutes : "<<minutes << std::endl;};
<span>	</span>
<span>	</span>MyTime operator *(const int &t) const;


<span>	</span>friend MyTime operator *(int k,const MyTime &t);<span>	</span>//使用友元函数<span>			</span>//const型成员函数,const型对象只能访问const型成员函数
};


void Remote::setTime(MyTime &otime,MyTime &ntime)
{
<span>	</span>ntime.hours=otime.hours;
<span>	</span>ntime.minutes=otime.minutes;
<span>	</span>ntime.seconds=otime.seconds;
}


MyTime MyTime::operator *(const int &t) const
{
<span>	</span>MyTime result;
<span>	</span>long totalminutes = hours*t*60+minutes*t;
<span>	</span>result.hours = totalminutes/60;
<span>	</span>result.minutes = totalminutes%60;
<span>	</span>return result;
}
MyTime operator *(int k,const MyTime &t)
{
<span>	</span>return t*k;
}


#endif

 

成员函数的已经包括在这里面了

<span style="font-family: Arial, Helvetica, sans-serif;">	</span><span style="font-family: Arial, Helvetica, sans-serif;">friend MyTime operator *(int k,const MyTime &t);</span><span style="font-family: Arial, Helvetica, sans-serif;">	</span><span style="font-family: Arial, Helvetica, sans-serif;">//使用友元函数</span><span style="font-family: Arial, Helvetica, sans-serif;">	</span>
就是这句

测试代码:

//--------mytime.cpp


#include <iostream>
#include "mytime.h"


int main()
{
	MyTime time(1,1,2);
	MyTime time2 =2*time;
	
	time2.showtime();
	
	Remote remote(1);
	remote.setTime(time,time2);
	time.showtime();
	
	
	return 0;
}

输出:



3、实际应用

友元运算符重载:


class X{		//运算符重载	——友元函数
	private:
	int x;
	public:
	X(int m){x=m;};
	X(X &y){x=y.get();};
	~X(){};
	int get(){return x;};
	void set(int y){x=y;};
	friend std::ostream & operator << (X &x1,std::ostream &os){os<<"friend 1os:"<<x1.x;return os;  };<span style="white-space:pre">	</span>//第一个友元函数<span style="white-space:pre">			</span>//友元函数,不是类的成员函数
	 friend std::ostream & operator << (std::ostream &os,X &x1){os<<"friend 2os:"<<x1.x;return os;  }
	
};

int main()
{	X x(1);
	//x.operator<<(y,std::cout);	//重载<<的一些尝试
<span style="white-space:pre">	</span>std::cout<<x;<span style="white-space:pre">			</span>//调用第二个
<span style="white-space:pre">	</span>x<<std::cout;<span style="white-space:pre">			</span>//调用第一个
	return 0;
}
测试输出:



<pre name="code" class="cpp">

 可以看出 
std::cout<<x;
调用的是
 friend std::ostream & operator << (std::ostream &os,X &x1){os<<"friend 2os:"<<x1.x;return os;  }
至于为什么是这样,我也没找到答案,但是直观看就应该是这样,估计是编译器的事了!

就像为什么重载 << 要用 operator << 这样做为约定一样!


<pre name="code" class="cpp">

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值