CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
英特尔®游戏设计大赛100美元现金周周送 专题改版:Java Web 专题
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  C/C++ >  C++ 语言

关于运算符重载?

楼主fxc123(大葱)2003-11-01 03:36:57 在 C/C++ / C++ 语言 提问

请问运算符重载是否只能是成员函数或者是类的友员?  
  我在一个程序中重载了<<,若加上友员就能编译通过,不加就说:  
  binary'<<':no   operator   defined   wich   takes   a   right-hand   operand   of   type'class   XX'???? 问题点数:0、回复次数:11Top

1 楼telantlan(宇翔)回复于 2003-11-01 08:25:51 得分 0

给你一到程序看看:  
  #include   <iostream>  
  #include   <ctype.h>  
  #include   <stdlib.h>  
  #include   <vector>  
  #include   <list>  
  #include   <algorithm>  
   
  using   namespace   std;  
   
  class   Variable   {  
  public:  
          char   id;  
          int   exp;  
   
          Variable()   {   //   required   by   <vector>;  
          }  
          Variable(char   c,   int   i)   {  
                  id   =   c;   exp   =   i;  
          }  
          bool   operator==   (const   Variable&   v)   const   {    
                  return   id     ==   v.id     &&   exp   ==   v.exp;  
          }  
          bool   operator<   (const   Variable&   v)   const   {   //   used   by   sort();  
                  return   id   <   v.id;  
          }  
  };  
   
  class   Term   {  
  public:  
          Term()   {  
                  coeff   =   0;  
          }  
          int   coeff;  
           
  vector<Variable>   vars;  
          bool   operator==   (const   Term&)   const;  
          bool   operator!=   (const   Term&   term)   const   {   //   required   by   <list>  
                  return   !(*this   ==   term);  
          }  
          bool   operator<   (const   Term&)   const;  
          bool   operator>   (const   Term&   term)   const   {     //   required   by   <list>  
                  return   *this   !=   term   &&   (*this   <   term);  
          }  
          int   min(int   n,   int   m)   const   {  
                  return   (n   <   m)   ?   n   :   m;  
          }  
  };  
   
  class   Polynomial   {  
  public:  
          Polynomial()   {  
          }  
          Polynomial   operator+   (Polynomial&);  
          void   error(char   *s)   {  
                  cerr   <<   s   <<   endl;   exit(1);  
          }  
  private:  
          list<Term>   terms;  
          friend   istream&   operator>>   (istream&   in,   Polynomial&   polyn)   {  
                  char   ch,   sign,   coeffUsed,   id;  
                  int   exp;  
                  Term   term;  
                  in   >>   ch;  
                  while   (true)   {  
                          coeffUsed   =   0;  
                          if   (!isalnum(ch)   &&   ch   !=   ';'   &&   ch   !=   '-'   &&   ch   !=   '+')  
                                    polyn.error("Wrong   character   entered2");  
                          sign   =   1;  
                          while   (ch   ==   '-'   ||   ch   ==   '+')   {   //   first   get   sign(s)   of   Term  
                                    if   (ch   ==   '-')  
                                                sign   *=   -1;  
                                    ch   =   in.get();  
                                    if   (isspace(ch))  
                                                in   >>   ch;  
                          }  
                          if   (isdigit(ch))   {                             //   and   then   its   coefficient;  
                                    in.putback(ch);  
                                    in   >>   term.coeff;  
                                    ch   =   in.get();  
                                    term.coeff   *=   sign;  
                                    coeffUsed   =   1;  
                          }  
                          else   term.coeff   =   sign;  
          //int   i;  
                          for   (int   i   =   0;   isalnum(ch);   i++)   {   //   process   this   term:  
                                  id   =   ch;                                         //   get   a   variable   name  
                                  ch   =   in.get();  
                                  if   (isdigit(ch))   {                     //   and   an   exponent   (if   any);  
                                            in.putback(ch);  
                                            in   >>   exp   >>   ch;  
                                  }  
                                  else   exp   =   1;  
                                  term.vars.push_back(Variable(id,exp));  
                          }  
                          polyn.terms.push_back(term);         //   and   include   it   in   the   linked   list;  
                          term.vars.resize(0);          
                          if   (isspace(ch))  
                                    in   >>   ch;  
                          if   (ch   ==   ';')                                     //   finish   if   a   semicolon   is   entered;  
                                    if   (coeffUsed   ||   i   >   0)  
                                              break;  
                                    else   polyn.error("Term   is   missing");     //   e.g.,   2x   -   ;   or   just   ';'  
                          else   if   (ch   !=   '-'   &&   ch   !=   '+')                       //   e.g.,   2x     4y;  
                                    polyn.error("wrong   character   entered");  
                  }  
                  for   (list<Term>::iterator   it   =   polyn.terms.begin();   it   !=   polyn.terms.end();   it++)  
                          if   (it->vars.size()   >   1)  
                                  sort(it->vars.begin(),it->vars.end());  
                  return   in;  
          }  
   
          friend   ostream&   operator<<   (ostream&   out,   const   Polynomial&   polyn)   {  
                  int   afterFirstTerm   =   0,   i;  
                  for   (list<Term>::const_iterator   pol   =   polyn.terms.begin();   pol   !=   polyn.terms.end();   pol++)   {  
                          out.put('   ');  
                          if   (pol->coeff   <   0)                           //   put   '-'   before   polynomial  
                                    out.put('-');                             //   and   between   terms   (if   needed);  
                          else   if   (afterFirstTerm)                 //   don't   put   '+'   in   front   of  
                                    out.put('+');                             //   polynomial;  
                          afterFirstTerm++;  
                          if   (abs(pol->coeff)   !=   1)               //   print   a   coefficient  
                                    out   <<   '   '   <<   abs(pol->coeff);//   if   it   is   not   1   nor   -1,   or  
                          else   if   (pol->vars.size()   ==   0)   //   the   term   has   only   a   coefficient  
                                    out   <<   "   1";                                
                          else   out.put('   ');  
                          for   (i   =   1;   i   <=   pol->vars.size();   i++)   {  
                                    out   <<   pol->vars[i-1].id;               //   print   a   variable   name  
                                    if   (pol->vars[i-1].exp   !=   1)         //   and   an   exponent,   only  
                                              out   <<   pol->vars[i-1].exp;   //   if   it   is   not   1;  
                          }  
                  }  
                  out   <<   endl;  
                  return   out;  
          }  
  };  
   
  //   two   terms   are   equal   if   all   varibles   are   the   same   and  
  //   corresponding   variables   are   raised   to   the   same   powers;  
  //   the   first   cell   of   the   node   containing   a   term   is   excluded  
  //   from   comparison,   since   it   stores   coefficient   of   the   term;  
   
  bool   Term::operator==   (const   Term&   term)   const   {  
          int   i;  
          for   (i   =   0;   i   <   min(vars.size(),term.vars.size())   &&  
                                          vars[i]   ==   term.vars[i];   i++);  
          return   i   ==   vars.size()   &&   vars.size()   ==   term.vars.size();  
  }  
   
  bool   Term::operator<   (const   Term&   term2)   const   {   //   used   by   sort();  
          if   (vars.size()   ==   0)  
                  return   false;                       //   *this   is   just   a   coefficient;  
          else   if   (term2.vars.size()   ==   0)  
                  return   true;                         //   term2   is   just   a   coefficient;  
          for   (int   i   =   0;   i   <   min(vars.size(),term2.vars.size());   i++)  
                  if   (vars[i].id   <   term2.vars[i].id)  
                            return   true;               //   *this   precedes   term2;  
                  else   if   (term2.vars[i].id   <   vars[i].id)  
                            return   false;             //   term2   precedes   *this;  
                  else   if   (vars[i].exp   <   term2.vars[i].exp)  
                            return   true;               //   *this   precedes   term2;  
                  else   if   (term2.vars[i].exp   <   vars[i].exp)  
                            return   false;             //   term2   precedes   *this;  
          return   ((int)vars.size()   -   (int)term2.vars.size()   <   0)   ?   true   :   false;  
  }  
   
  Polynomial   Polynomial::operator+   (Polynomial&   polyn2)   {  
          Polynomial   result;  
          list<Term>::iterator   p1,   p2;  
          bool   erased;  
          for   (p1   =   terms.begin();   p1   !=   terms.end();   p1++)   //   create   a   new   polyn  
                  result.terms.push_back(*p1);                                     //   from   copies   of   *this  
          for   (p1   =   polyn2.terms.begin();   p1   !=   polyn2.terms.end();   p1++)   //   and  
                  result.terms.push_back(*p1);                                     //   polyn2;  
          for   (p1   =   result.terms.begin();   p1   !=   result.terms.end();   )   {  
                  for   (p2   =   p1,   p2++,   erased   =   false;   p2   !=   result.terms.end();   p2++)  
                          if   (*p1   ==   *p2)   {                           //   if   two   terms   are   equal   (except  
                                    p1->coeff   +=   p2->coeff;     //   for   the   coefficient),   add   the  
                                    result.terms.erase(p2);     //   two   coefficients   and   erase  
                                    if   (p1->coeff   ==   0)             //   a   redundant   term;   if   the    
                                            result.terms.erase(p1);//   coefficient   in   retained   term    
                                    erased   =   true;                           //   is   zero,   erase   the   term   as   well;  
                                    break;  
                          }  
                  if   (erased)                 //   restart   processing   from   the   beginning  
                            p1   =   result.terms.begin();     //   if   any   node   was   erased;  
                  else   p1++;  
          }  
          result.terms.sort();  
          return   result;  
  }  
   
  void   main()   {  
          Polynomial   polyn1,   polyn2;  
          cout   <<   "Enter   two   polynomials,   each   ended   with   a   semicolon:\n";  
          cin     >>   polyn1   >>   polyn2;  
          cout   <<   "The   result   is:\n"   <<   polyn1   +   polyn2;  
  }  
   
  Top

2 楼leyt(思维机器)回复于 2003-11-01 10:28:25 得分 0

是的Top

3 楼Andy84920(你也不懂)回复于 2003-11-01 16:23:32 得分 0

操作符重载函数可以是一个普通函数,成员函数,友元函数.Top

4 楼lemon520(喷血)回复于 2003-11-01 17:11:12 得分 0

要是成员和友员之一Top

5 楼fierygnu(va_list)回复于 2003-11-01 17:33:10 得分 0

不能是普通函数。Top

6 楼kdush(迷茫过后……还是迷茫……) (love—>kula始终未变)回复于 2003-11-01 18:05:57 得分 0

小弟也是C++初学者,不过小弟在C++大学教程中看到这样的话,或许对你有帮助!  
  ·运算符函数可以是成员函数也可以是非成员函数--(友元函数也是非成员函数吧)。  
  ·当运算符是一个成员函数时,最左边的操作数必须是运算符类的一个类对象(或者对该类对象的引用)  
  ·如果左边的操作数必须是一个不同的类的对象,该运算符函数必须作为一个非成员函数来实现。  
              重载<<运算符必须有一个类型为   ostream&   的左操作数(例如表达式cout<<classObject中的cout),因此它必须是一个非成员函数。  
   
  Top

7 楼cyh811122(人生不如意)回复于 2003-11-01 20:03:51 得分 0

<<也可以用成员函数做只不过麻烦了一些没有必要呀Top

8 楼konhon(优华)回复于 2003-11-01 20:07:43 得分 0

重载<<或>>操作符它必须是一个非成员函数.  
  Top

9 楼telantlan(宇翔)回复于 2003-11-04 20:30:30 得分 0

不好意思,各位,是小弟菜,把"(英文输入)打成"(全拼输入);当时看到unknow   char以为不可能错,原来切换了输入法,不应该,不应该.:)Top

10 楼dot99(又来混CSDN来了)回复于 2003-11-04 20:42:15 得分 0

。。。。。。。。。。。。。。。。。。。。。。Top

11 楼houdy(致力于图像/图形领域,成为有思想的程序员)回复于 2003-11-05 12:12:44 得分 0

操作符只能有成员和友元这两种,对于有些操作符,成员函数和友元的差别不大,差别就在于参数个数的不同,但是有的操作符(比如赋值操作符)只能是成员函数。详情可以参阅<Thinking   in   C++>里面关于operator   overload这一章,讲的很清楚。Top

相关问题

  • 重载运算符
  • 怎样重载(),[],=运算符
  • 如何重载+运算符?
  • 关于运算符重载。。
  • 关于运算符重载
  • 如何重载运算符<<
  • 能否重载()运算符?
  • 关于运算符重载
  • 关于运算符重载
  • 重载二元运算符

关键词

  • 函数
  • exp
  • polyn
  • terms
  • 操作符
  • coeff
  • ch
  • erased
  • coeffused
  • coefficient

得分解答快速导航

  • 帖主:fxc123

相关链接

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

广告也精彩

反馈

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