wejianzhan是什么网站,微分销系统软件,无锡市新区建设环保局网站,个人网站 可以做淘宝客吗在之前的友元中就曾经讲过#xff0c;我们为了去访问修改私有成员中的数据时#xff0c;只能通过公有的办法去进行访问操作#xff0c;非常的局限。所以C引用了友元函数#xff0c;只要加上friend关键字#xff0c;C的这个类#xff0c;会自动把这个函数的权限拉到类内我们为了去访问修改私有成员中的数据时只能通过公有的办法去进行访问操作非常的局限。所以C引用了友元函数只要加上friend关键字C的这个类会自动把这个函数的权限拉到类内这样就可以访问私有成员了。
上一篇文章讲了重载运算符的操作。但有些运算符不能够在类内进行重载例如输入输出的符号。下面我会详细讲为什么不能在类内进行重载。
这里我们先假设有一个类
A{}//功能暂且不写知道是个类就行了
首先普通类内重载会自带一个this指针指向用此函数的对象。这被称作第一操作数。
如果在定义号的时候实际上是并不是简单的类对象某某亦或是某某类对象
它实际上全部的写法应该是
A a; //这里定义了一个对象a
a.operator某某); //这是全部写法也是正常情况应该写的情况只是我们平时简写编译器仍然认识罢了。
a某某 // 这是我们平时的写法
比如你想重载或者符号这种情况他的第一操作符就一定不是类本身例如
A a;
我们不可能写成a或者是a我们正常的写法应该是cin a;cout a;
这里第一操作符并不是a这个对象而是cin/cout。这是ios的输入输出的参数。 这里有人就要问了那类对象某某我也可以写成某某类对象这里实际上是交换律因为这里类对象写的地方并不是唯一的可以进行交换这种情况可以不算。 话不多说我们使用代码来进行讲解下面先给大家展示时间类运算符重载作为对比我先写类内成员函数重载再写类外友元重载大家可以复制下来看看。
#include iostream
#include string
using namespace std;/*
* 1.类的成员 在类内的运算符重载函数的第一个操作数一定是类的对象
* 总结:
* 有的情况运算符必须写成非成员函数.这个函数如果需要获得类对象的私有数据,则有如下方法
* 1.可以利用交换律(前提是类已经实现该运算符的重载.1.5*t-t*1.5)
* 2.类把该函数声明为它的友元函数
* 3.类提供获取私有数据的公有方法
*
* 举例如下
*/
class Time
{
private:int hours;//小时int minutes;//分钟
public:Time(int h 0, int m 0) :hours(h), minutes(m)//构造函数{}Time operator (const Time t)const;//重载 ,注意返回值不是引用Time operator -(const Time t)const//重载 -{int tmp (hours * 60 minutes) - (t.hours * 60 t.minutes);//分钟return Time(tmp / 60, tmp % 60);}Time operator *(double n)const;//重载 * .含义;3:40 * 3 -11小时0分//3*3:40 不是void show() const;//提供获得时间的公有方法/* int GetHours()const{return hours;}int GetMinutes()const{return minutes;}*/
};Time Time::operator(const Time t)const //2:302:45
{return Time(hours t.hours (minutes t.minutes) / 60, (minutes t.minutes) % 60);
}Time Time::operator *(double n)const // Time * 小数
{double tmp (hours * 60 minutes) * n;return Time{ (int)tmp / 60,(int)tmp % 60 };
}void Time::show() const
{cout hours 小时, minutes 分钟 endl;
}Time operator*(double n,const Time t)//普通函数的形式重载*
{//double tmp n * (t.hours * 60 t.minutes);//错误,这个函数不是Time成员,不能访问它的私有// int tmp (int)(n * (t.GetHours() * 60 t.GetMinutes()));// return Time(tmp/60,tmp%60);return t * n;//前提:已经实现了 t*n
}int main()
{Time t1{ 2,35 };Time t2 { 2,40 };Time t3 t1 t2;//t1.operator(t2);Time t4 t2 - t1;//t2.operator-(t1);Time t5 t1 * 1.5;Time t6 1.5 * t1;//没有实现 小数*时间t3.show();t4.show();t5.show();t6.show();//t1 * 3;//t1.operator*(3);//3*t1;//3.*(t1);//在3这个int类 没有实现对Time的*重载return 0;
}
接下来作为对比我继续把重载输入输出的代码。 #include iostream
#include string
using namespace std;class Time
{
private:int hours;//小时int minutes;//分钟public:Time(int h 0, int m 0);void show() const;//void operator (ostream os)//os是输出流对象的引用//{// os hours 小时,, minutes 分钟 endl;//}friend Time operator *(double n, const Time t);//这个是Time的友元函数friend ostream operator (ostream os, const Time t);//这个是Time的友元函数//实现 运算符重载 istreamfriend istream operator (istream is, Time t);
};Time::Time(int h, int m)
{hours h;minutes m;
}void Time::show() const
{cout hours 小时, minutes 分钟 endl;
}Time operator *(double n, const Time t)
{int tmp (int)(n * (t.hours * 60 t.minutes));return Time(tmp/60,tmp%60);
}ostream operator (ostream os, const Time t)//os不加const,需要把数据写入到输出流
{os t.hours 小时,, t.minutes 分钟 endl;return os;
}istream operator (istream is, Time t)
{return is t.hours t.minutes;
}int main()
{Time t1 { 2,35 };Time t2 { 2,40 };Time t3 1.5*t1; //第一个操作数不是类对象,所以只能是非成员函数//t3.show();//t3 cout; //可以作为类成员函数的,但不能理解cout t3;//这个不能调用t3的成员函数,但我们需要cout t1 t2;cin t1; //5 30cout t1;//5小时,30分钟// cout t3 ;//错误,没有实现如何 cout Time的对象//cout 是 ostream类对象 ; cin是istream类对象return 0;
}每日金句 一步一行便无惧陷入泥沼 ---------------银枝