为什么operator运算符重载一定要为友元函数定义

君,已阅读到文档的结尾了呢~~
C++ 第06章 运算符重载与友元(日)C+,友元,和,第06章,运算符重载,和友元,与友元,2013年,运算符
扫扫二维码,随身浏览文档
手机或平板扫扫即可继续访问
C++ 第06章 运算符重载与友元(日)
举报该文档为侵权文档。
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
推荐理由:
将文档分享至:
分享完整地址
文档地址:
粘贴到BBS或博客
flash地址:
支持嵌入FLASH地址的网站使用
html代码:
&embed src='/DocinViewer--144.swf' width='100%' height='600' type=application/x-shockwave-flash ALLOWFULLSCREEN='true' ALLOWSCRIPTACCESS='always'&&/embed&
450px*300px480px*400px650px*490px
支持嵌入HTML代码的网站使用
您的内容已经提交成功
您所提交的内容需要审核后才能发布,请您等待!
3秒自动关闭窗口hackfreer 的BLOG
用户名:hackfreer
文章数:532
评论数:210
访问量:1228508
注册日期:
阅读量:5863
阅读量:12276
阅读量:378272
阅读量:1070946
51CTO推荐博文
&运算符在重载的时候有两种方式,一是成员函数方式,二是成友元(friend)函数方式。&
成员函数比较简单。下面是一个示例代码:&
class Complex&
Complex(){}&
Complex(double i,double j):real(i),img(j)&
&&&&&&& Complex operator+(const Complex &cx)&
&&&&&&& {&
&&&&&&&&&&&&&&& return Complex(real+cx.real,img+cx.img);&
&&&&&&& }&
如果是设置成友元函数,一定要注意:&
(1)当重载友元函数时,将没有隐含的参数this指针。这样,对双目运算符,友元函数有2个参数,对单目运算符,友元函数有一个参数。&
(2)有些运行符不能重载为友元函数,它们是:=,(),[]和->。&
因此,上面那个+运算符如果是重载为友元函数的话,应该写成:&
class Complex&
&&& public:&
&&& Complex(){}&
&&& Complex(double i,double j):real(i),img(j)&
&&& //& 注意: 有两个参数&
&&& friend Complex operator+(const Complex &cx1,const Complex &cx2)&
&&&&&&& return Complex(cx1.real+cx2.real,cx1.img+cx2.img);&
&&& void Out()&
&&&&&&& cout && real && &+& && img && &i& &&&
还需要注意一点,有的VC 6.0编译器在编译上面代码的时候会报错,错误为:&
fatal error C1001: INTERNAL COMPILER ERROR&
原因是VC编译器本身的问题。&
解决办法:&在类的声明之前再加上一个声明。具体代码如下:&
Complex operator+(const Complex &cx1,const Complex &cx2);&
class Complex&
Complex(){}&
Complex(double i,double j):real(i),img(j)&
// 注意:有两个参数&
friend Complex operator+(const Complex &cx1,const Complex &cx2)&
return Complex(cx1.real+cx2.real,cx1.img+cx2.img);&
void Out()&
cout && real && &+& && img && &i& &&&
这样就没有问题了。
了这篇文章
类别:┆阅读(0)┆评论(0)& 鸡啄米:C++编程入门系列之四十七(多态性:运算符重载为类的友元函数)
鸡啄米:C++编程入门系列之四十七(多态性:运算符重载为类的友元函数)
&&&&& &鸡啄米在上一节中讲了的方式和规则,这一节接着讲运算符重载的另一种方式--运算符重载为类的友元函数。&&&&&&&在中,鸡啄米讲到过,友元函数通过类的对象可以访问类的公有、保护和私有成员,也就是类的所有成员友元函数都能访问到。所以运算符重载为类的友元函数以后也可以访问类的所有成员。&&&&&& 与运算符重载为成员函数时不同的是,重载的友元函数不属于任何类,运算符的操作数都需要通过函数的形参表传递。操作数在形参表中从左到右出现的顺序就是用运算符写表达式时操作数的顺序。&&&&&& 这里也分双目运算符和单目运算符两种情况讨论运算符重载为友元函数的具体方式。&&&&&&&如果有U,它的其中一个操作数是类A的对象a,那么运算符U就可以重载为类A的友元函数,此友元函数的两个参数中,一个是类A的对象,另一个是其他对象,也可以是类A的对象。这样双目运算符重载为类的友元函数后,假设运算符的两一个操作数是对象b,则表达式a U b就相当于调用函数operator U(a, b)。&&&&&&&下面再讨论的重载。如果有前置单目运算符U,比如前置&--&,a为类A的对象,我们想实现U a这样的运算,就可以把U重载为类A的友元函数,此友元函数只有一个形参,为类A的对象,重载后表达式U a相当于调用函数operator U(a)。如果是后置单目运算符U,如后置&++&,a还是类A的对象,那么要实现a U这样的运算,也可以把U重载为类A的友元函数,此时友元函数就需要有两个形参,一个是类A的对象,另一个是整型形参,此整型形参没有实际意义,与上一节后置单目运算符重载为成员函数时的整型形参一样,只是为了区分前置运算符和后置运算符的重载。重载后表达式a U就相当于调用函数operator U(a, 0)。&&&&&&&鸡啄米将上一节中第一个例子中的运算符重载改为友元函数,再简单介绍下要实现的功能:时间值的加法,比如2个小时20分钟加3个小时30分钟,应该是5个小时50分钟,运算规则就是小时数相加,分钟数相加,如果分钟数的和超过60分钟则小时数再加1,分钟数减60。双目运算符&+&需要重载为时间值类的友元函数,此函数有两个形参,类型都是时间值类的对象。&&& &&&&&& #include &iostream&&&&&&&&&&&&& class CTimeSpan&&&&&& {&&&&&& public:&&&&&&&&&&&&&&&&&& CTimeSpan(int nHours=0, int nMins=0);&&&&& // 构造函数&&&&&&&&&&&&&&&&&& friend CTimeSpan operator +(CTimeSpan ts1, CTimeSpan ts2); // 运算符&+&重载为成员函数&&&&&&&&&&&&&&&&&& int GetHours()&&&&& { return m_nH }&& // 获取小时数&&&&&&&&&&&&&&&&&& int GetMins()&&&&&& { return m_nM }&&& // 获取分钟数&&&&&&&&&&&&&&&&&& void Show();&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& // 显示时间值&&&&&& private:&&&&&&&&&&&&&&&&&& int m_nH&&&&&& // 小时数&&&&&&&&&&&&&&&&&& int m_nM&&&&&&& // 分钟数&&&&&& };&&&&&& CTimeSpan::CTimeSpan(int nHours, int nMins)&&&&&&&&& // 构造函数的实现&&&&&& {&&&&&&&&&&&&&&&&& nHours += nMins/60;&&&&&&&&&&&&&&&&& nMins %= 60;&&&&&&&&&&&&&&&&& m_nHours = nH&&&&&&&&&&&&&&&&& m_nMins = nM&&&&&& }&&&&&& void CTimeSpan::Show()&&&&&& {&&&&&&&&&&&&&&&& cout && m_nHours && &小时& && m_nMins && &分钟& &&&&&&&& }&&&&&& CTimeSpan operator +(CTimeSpan ts1, CTimeSpan ts2)& // 重载运算符函数实现&&&&&& {&&&&&&&&&&&&&&&&& int nNewH&&&&&&&&&&&&&&&&& int nNewM&&&&&&&&&&&&&&&&& nNewHours = ts1.m_nHours + ts2.m_nH&&&&&&&&&&&&&&&&& nNewMins = ts1.m_nMins + ts2.m_nM&&&&&&&&&&&&&&&&& nNewHours += nNewMins/60;&&&&&&&&&&&&&&&&& nNewMins %= 60;&&&&&&&&&&&&&&&&& return CTimeSpan(nNewHours, nNewMins);&&&&&& }&&&&&& int main()&&&&&& {&&&&&&&&&&&&&&&& CTimeSpan timeSpan1(2, 50);&&&&&&&&&&&&&&&& CTimeSpan timeSpan2(3, 30);&&&&&&&&&&&&&&&& CTimeSpan timeS&&&&&&&&&&&&&&&& timeSum = timeSpan1 + timeSpan2;&&&&&&&&&&&&&&&& cout && &timeSpan1: &;&&&&&&&&&&&&&&&& timeSpan1.Show();&&&&&&&&&&&&&&&& cout && &timeSpan2: &;&&&&&&&&&&&&&&&& timeSpan2.Show();&&&&&&&&&&&&&&&& timeSum = timeSpan1 + timeSpan2;&&&&&&&&&&&&&&&& cout && &timeSum=timeSpan1+timeSpan2: &;&&&&&&&&&&&&&&&& timeSum.Show();&&&&&&&&&&&&&&&& return 0;&&&&&& }&&&& & 程序运行结果:&&&&& &timeSpan1: 2小时50分钟&&&&&& timeSpan2: 3小时30分钟&&&&& &timeSum=timeSpan1+timeSpan2: 6小时20分钟&&&&&&&这个程序的主函数main与上一节例子的main函数完全相同,程序运行结果也一样。区别就是加法运算符重载为CTimeSpan类的友元函数而不是成员函数,我们看到运算符重载函数有两个形参ts1和ts2,通过这两个参数将需要进行运算的操作数传递进去,而在此函数中也能够访问类CTimeSpan的私有成员m_nHours和m_nMins。&&&&&& 这两节中鸡啄米给出的例子仅介绍了几个简单运算符的重载例子,对于其他如&%&、&&&&等运算符的重载可能有些不同,但是只要大家真正理解了重载方法,相信也很容易掌握其他运算符的重载。&&&&&& 好了,运算符重载的内容就讲完了。如果有问题欢迎到鸡啄米博客交流讨论。&
除非特别注明,文章均为原创
转载请标明本文地址:
作者:鸡啄米
&&( 22:13:7)&&( 21:53:54)&&( 21:25:32)&&( 22:23:2)&&( 22:4:45)&&( 22:22:20)&&( 21:39:22)&&( 23:24:41)&&( 23:12:31)&&( 22:38:42)
C++完整篇啊强大的,学习了鸡啄米 于
13:18:30 回复c++基本知识点大部分都覆盖到了,呵呵,有需要的来学习交流啊。
C太强大了 、
这个,挺厉害的!
C语言不知道好不好学习呢?当个程序员也不容易的吧。鸡啄米 于
22:55:20 回复其实不算多么很难,有耐心就行。程序猿是真的不容易啊。。。
C语言好呢还是vc?鸡啄米 于
22:55:54 回复c是语言,vc是编译器,呵呵
大过年的,怎么还在学习编程?鸡啄米 于
23:00:03 回复俺还上班呢,还在编程中,呵呵
都放假了,看看博主偷懒了没有!
正常的工作开始了!!
又要张大一岁了!!鸡啄米 于
23:00:30 回复不愿再长大了
C语言?我有点无语
大学的专业
最后也只是知道个定义
好文章啊 !支持您!!!
在主函数中,为什么“timeSum = timeSpan1 + timeSpan2;”要出现两次啊?
楼主,我觉得可以运算符重载可以不需要使用成员函数和友元函数,直接用类的GetHours()和GetMins()就可以:CTimeSpan operator +(CTimeSpan ts1, CTimeSpan ts2)
// 重载运算符函数实现{ int nNewH int nNewM nNewHours = ts1.GetHours() + ts2.GetHours(); nNewMins = ts1.GetMins() + ts2.GetMins(); nNewHours += nNewMins / 60; nNewMins %= 60; return CTimeSpan(nNewHours, nNewMins);}
完全随机文章一.一般形式
返回类型 operator 操作符 (参数列表)
二.成员函数or友元函数?
大部分运算符重载函数既可以是成员函数,也可以使友元函数。使用友元函数的形式如下:
& & & & friend 返回类型 operator 操作符 (参数列表)
& & & & eg:
& & & & 成员函数:Int operator + (const Int &);
& & & & 友元函数:friend Int operator + (const Int &, const Int &);
& & & &&&注意:跟成员函数不同的是参数列表。友元函数的参数列表中比成员函数多一个参数,因为成员函数可以通过this指针隐式的访问对象的参数,而友元必须指定。
运算符重载函数定义为成员函数或是友元函数的几点依据:
&重载运算符(),【】,-&或任意赋值运算符时,必须为成员函数
当运算符重载函数是一个成员函数时,最左边的操作数必须是类的一个对象(或引用),例如上例中+左边为Int。如果左边的操作数必须是一个不同类的对象或内部类型的对象,运算符函数必须是友元函数。(解释:通过成员函数重载的运算符是由运算符左边的对象调用的,该对象通过this指针隐式传递,因此,最左边的操作数必须是一个对象。将运算符重载函数声明为友元函数时,因为没有隐含的this指针,所以必须显示指定所有参数。)
对二元运算符,成员函数带一个参数,友元函数带两个参数。对一元运算符,成员函数不带参数,友元函数带一个阐述。
三.可重载or不可重载的运算符
不可被重载的运算符:
.*, & &::, & &?:, & &sizeof
1.前置后置运算符如何区分?
前置:Integer& operator ++ () & & & & & &friend Integer& operator ++(Integer & a);
后置:Integer operator ++ (int) & & & & & &friend Integer operator ++ (Integer & a, int);
int只是一个伪值,用于区分前置后置运算符
阅读(...) 评论()先看下操作重载的定义和要求:
要进行操作符重载首先要求是自定义类型的运算
写法格式:返回值 operator运算符(参数列表){}
重载的要求:
1、内置类型的操作符不能被重载
2、不能为内置类型定义其他的操作符
3、操作符重载不能改变操作符的优先级
4、操作数个数不能改变
重载运算符时,函数声明在类内和类外是有区别的,比方说+-*/等需要2个操作数的运算符,
当声明在类的外部时,则参数列表为2个参数,第一个参数为运算符左边的操作数,而第二个参数为
操作符右边的操作数:如下
classType operator+(classType& left, classType& right);
而当函数声明在类的内部时,即为类的成员函数时,
classType operator+(classType& right );
而第一个操作数就是调用该操作符的对象的引用,第二个操作数是传进来的参数,
所以,如果要重载&&运算符,一般写法是这样的
ostream& operator&&(ostream& os, const classType& obj);
则第一个参数是该运算符的第一个操作数,然而,却不是类对象,
所以当该类运算符重载时写在类的内部时,又为了访问类内除public外的其它变量或函数,
则应当声明为友元函数:
friend ostream& operator&&(ostream& os, const classType& obj);
所以,为什么有些运算符的重载要声明为友元函数,是类似的。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:3773次
排名:千里之外
原创:41篇
(1)(2)(3)(3)(2)(2)(33)(1)}

我要回帖

更多关于 友元函数定义 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信