CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
IBM Rational 系统开发最佳实践工具包 WebSphere MQ 最佳实践 TOP 15
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  C/C++ >  新手乐园

友元函数

楼主yuchen2006(雨晨)2006-03-16 16:36:05 在 C/C++ / 新手乐园 提问

这个程序使用了操作符重载函数  
  #include<iostream.h>  
  class   a  
  {  
  private   :  
  int   i;  
  public:  
  a()  
  {  
  i=1;  
  }  
  a(int   x)  
  {  
  i=x;  
  }  
  display()  
  {  
  cout<<i;  
  }  
        a&   operator   *(int   num)     //操作符重载函数  
  {  
  this->i=this->i*num;  
  return   (*this);  
  }        
  };  
  void   main()  
  {  
  a   a1(10);  
  a   a2;  
  a2=a1*20;     //这里调用了操作符重载函数   a2=a1.operator   *(int   20)  
  a2.display()   ;  
  }  
  这个程序运行没有任何问题,只是不明白一点  
  第一个问题:重载函数中为什么要返回引用,有什么意义,我试了一下,去掉它结果也是没问题的,帮解释一下。  
   
  请再看这个程序  
  #include<iostream.h>  
  class   a  
  {  
  private   :  
  int   i;  
  public:  
  a()  
  {  
  i=1;  
  }  
  a(int   x)  
  {  
  i=x;  
  }  
  display()  
  {  
  cout<<i;  
  }  
        a&   operator   *(int   num)  
  {  
  this->i=this->i*num;  
  return   (*this);  
  }  
  friend     a&   operator   *(int   num,a   &temp);//?这里为什么要声明成友元,去掉它为什么会报错,构成重载不可以吗?  
         
  };  
   
  a&   operator   *(int   num,a   &temp)  
  {  
  return   (temp*num);  
  }  
  void   main()  
  {  
  a   a1(10);  
  a   a2;  
  a2=20*a1;//?显示调用的格式的什么?是不是a2=20.operator*(a   &a1)?这里用友元是解决这种格式的问题,可为什么使用友元能解决这种问题?  
  a2.display()   ;  
  }  
  这个程序和上个程序的区别是上面那个是a2=a1*20;这个程序是a2=20*a1;这个语句对编译器来说没有意义,要想正常运行程序,需要使用友元函数解决这个问题。  
   
  第二个问题:为什么要用友元函数,我知道友元函数是为了访问其他类中的成员的,这里使用友元来解决这个问题,不大理解,去掉friend还报错,为什么?  
   
  第三个问题:a2=20*a1;显示调用的格式是什么?? 问题点数:30、回复次数:9Top

1 楼hyallentong(Caniggia)回复于 2006-03-16 16:50:19 得分 3

重载函数中为什么要返回引用?  
  实现连乘   如   a1*a2*a3……Top

2 楼yinqing_yx(淘汰引擎)(玩虚一族)回复于 2006-03-16 16:53:35 得分 4

第一个问题:重载函数中为什么要返回引用,有什么意义,我试了一下,去掉它结果也是没问题的  
  答:用于实现链式表达  
   
  第二个问题:为什么要用友元函数,我知道友元函数是为了访问其他类中的成员的,这里使用友元来解决这个问题,不大理解,去掉friend还报错,为什么?  
  答:流插入操作符必须有一个类型为ostream&的左操作符,因此必须是一个非成员函数。而他们需要访问类的private成员,所以需要为友元函数  
   
  第三个问题:a2=20*a1;显示调用的格式是什么??  
  答:   20*a1     -------->       a1&   operator*(   20   )  
            a2   =   a1   赋值操作符~  
   
   
   
  Top

3 楼discory(discory)回复于 2006-03-16 17:28:09 得分 3

第一个问题我知道一点,单操作符重载只能重载左值,所以a2=a1*20对,  
  a2=20*a1不可能重载20,我也刚看到这里,不是很清楚Top

4 楼WonderInJYC(Learn_晕ing)回复于 2006-03-16 17:36:34 得分 3

第二个问题:friend     a&   operator   *(int   num,a   &temp);//?这里为什么要声明成友元,去掉它为什么会报错,构成重载不可以吗?  
   
  因为重载二元运算符时,用成员函数重载,它的左操作数必须为该类的对象.而友元函数则可以处理左右操作数不同的问题.Top

5 楼yuchen2006(雨晨)回复于 2006-03-16 18:26:40 得分 0

第二个问题:为什么要用友元函数,我知道友元函数是为了访问其他类中的成员的,这里使用友元来解决这个问题,不大理解,去掉friend还报错,为什么?  
  答:流插入操作符必须有一个类型为ostream&的左操作符,因此必须是一个非成员函数。而他们需要访问类的private成员,所以需要为友元函数  
   
  第三个问题:a2=20*a1;显示调用的格式是什么??  
  答:   20*a1     -------->       a1&   operator*(   20   )  
            a2   =   a1   赋值操作符~  
   
  "流插入操作符必须有一个类型为ostream&的左操作符"这句话的意思不明白,请帮解释,这里又流插入操作符吗??  
   
   
   
  我想a2=20*a1;是先调用的友元吧,然后友元中的temp*num调用了原来的操作符重载函数,如果是这样,a1&   operator*(   20   )这种格式就不大明白了  
   
  Top

6 楼ugg(逸学堂(exuetang.net))回复于 2006-03-16 20:26:26 得分 15

第一个问题:重载函数中为什么要返回引用,有什么意义,我试了一下,去掉它结果也是没问题的,帮解释一下。  
  ~~~~~~~~~  
  这个问题,首先明白返回引用和返回对象的区别,返回对象,要生成临时对象,lz可以通过跟随  
  对象的创建次数来测试。这时就会知道引用和返回对象的区别。  
  还有一个就是炼成的问题,a1   =   a1*a2*a3;如果不返回引用,将无法实现炼成。  
   
  第二个问题:为什么要用友元函数,我知道友元函数是为了访问其他类中的成员的,这里使用友元来解决这个问题,不大理解,去掉friend还报错,为什么?  
   
  第三个问题:a2=20*a1;显示调用的格式是什么??  
   
  其实二三关键就是对a1*20,和20*a1的理解,编译器要对表达式进行操作时,  
  首先要把表达式中的类型转换为相同类型,比如处理a1*20式,编译器首先找到  
  a1的类型,所以要利用a1对象中的*操作符号,但是发现*运算符,要求输入的是  
  int型,所以这时可以直接调用a1.operator*(20),其实如果lz修改为a&   operator   *(consta&   num)这样上面的操作也会成立,因为编译器会把a的构造函数a(int   x)把20身成一个a类型对象。  
  所以上面的修改会成功。  
  但是20*a1;编译器会想法把a1转换为int型进行操作。如果lz不用friend,可以重载int操作符号  
  operator   int()   const  
  {  
  return   i;  
  }  
  这样上面的表达式也正确,不会出错。  
  只是声明为friend后,20*a1;调用格式为  
  operator(20,a1);  
   
  Top

7 楼edwardrong(明年-今日)回复于 2006-03-17 01:45:48 得分 2

ugg(逸学堂(exuetang.net))    
  还有一个就是炼成的问题,a1   =   a1*a2*a3;如果不返回引用,将无法实现炼成。  
  ~~~~~~~~~~~~~~~~~~~~~~~~~  
  请问关于这点能给出一个例子解释一下吗?Top

8 楼yuchen2006(雨晨)回复于 2006-03-17 06:11:53 得分 0

ugg(逸学堂(exuetang.net))    
  还有一个就是炼成的问题,a1   =   a1*a2*a3;如果不返回引用,将无法实现炼成。  
  ~~~~~~~~~~~~~~~~~~~~~~~~~  
  请问关于这点能给出一个例子解释一下吗?  
   
  我试了试,不用返回引用没有问题啊,帮忙举个例子吧,多谢了  
  下面是我试的程序,没有返回引用  
  #include<iostream.h>  
  class   A  
  {  
  int   aa;  
  public:  
  A(int   x)  
  {  
  aa=x;  
  }  
  A   operator   *(A   duixiang)  
  {  
                    this->aa=this->aa*duixiang.aa;  
    return(*this);  
  }  
  void   display()  
  {  
  cout<<aa<<endl;  
  }  
  };  
  void   main()  
  {  
  A   a1(2),a2(3),a3(4);  
          a1=a1*a2*a3;  
  a1.display();  
  }Top

9 楼ugg(逸学堂(exuetang.net))回复于 2006-03-17 09:20:24 得分 0

a1   =   a1*a2*a3;  
  ~~~~~~~  
  上面的函数调用过程如下  
  a1.operator=(a1.operator*(a2.operator*(a3));  
  这里的主要问题是连乘出问题,而不是等号出问题。  
   
  所以楼上按下面的方法进行测试  
  a1*a2*a3;  
  a1.display();  
   
  在使用&符号后,a1可以得到正确值24,如果不是用引用符号,a1的值会为6。  
  这就是区别。而上面例子中由于使用=,相当于把连乘后的结果值赋值给a1,  
  而这个结果是一个临时对象,采用引用时使用=,这时只是相当于  
  a1*a2*a3;  
  a1=a1;  
  Top

相关问题

  • 友元函数、成员函数...
  • 关于友元函数
  • 友元函数问题?
  • 友元函数的问题
  • 友元函数问题。
  • 关于友元函数
  • 友元函数问题
  • 友元函数能否继承
  • 友元函数的一个问题!
  • 友元函数的重载问题

关键词

  • .net
  • 函数
  • 编译器
  • 用友
  • 解决
  • 操作符
  • 重载
  • 报错
  • 友元
  • 去掉

得分解答快速导航

  • 帖主:yuchen2006
  • hyallentong
  • yinqing_yx
  • discory
  • WonderInJYC
  • ugg
  • edwardrong

相关链接

  • C/C++ Blog
  • C/C++类图书
  • C/C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo