CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
可用分押宝游戏火热进行中... 专题改版:Java Web 专题
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  C/C++ >  工具平台和程序库

大家帮我看看一个操作符重载的问题

楼主fengchang(everate)2005-08-04 17:40:55 在 C/C++ / 工具平台和程序库 提问

#include     <fstream>  
  #include     <iostream>  
  #include   <complex>  
  using   namespace   std;  
  typedef   complex<double>   COMPLEX;  
  const   double   PI   =   3.1415926;  
  const   int   PIAngle   =   180;  
  static   double   MakeAngleFromRadian(double   dRadian)  
  {  
  double   dAngle   =   dRadian/PI*PIAngle;  
  if   (dAngle<-PIAngle)  
  dAngle   +=   2*PIAngle;  
  else   if   (dAngle>PIAngle)  
  dAngle   -=   2*PIAngle;  
  return   dAngle;//返回值的范围在[-180,180]之间;  
  }  
  ostream&   operator<<(ostream&   os,const   COMPLEX&   cpValue)  
  {  
      os<<abs(cpValue)<<"∠"<<MakeAngleFromRadian(arg(cpValue));  
      return   os;  
  }  
   
  void   main()  
  {    
    COMPLEX   cpxVale(0,0);  
  cout<<cpxVale<<endl;  
  ofstream   outfile("d:\\temp\\rst.txt");  
  outfile<<cpxVale<<endl;  
   
  }    
   
  代码如上,我想实现幅值/相角的输出,但是我发现输出到控制台的是符合设计思路的,输出到文件中的是默认的复数的输出。请大侠赐教,多谢了! 问题点数:40、回复次数:5Top

1 楼mayflowers(黯然神伤)回复于 2005-08-04 22:47:48 得分 0

For   class   complex   provides   the   common   I/O   operators   <<   and   >>:  
   
  template   <class   T,   class   charT,   class   traits>  
  std::basic_ostream<charT,   traits>&  
  operator<<   (std::basic_ostream<charT,   traits>&   strm,   const   std::complex<T>&   c);  
   
  ostream   and   ofstream   is   defined   in   std   as:  
  typedef   basic_ostream<char>   ostream;  
  typedef   basic_ofstream<char>   ofstream;  
   
  However,   the   basic_ofstream   derives   from   basic_ostream,   not   ostream.  
  So   the   compiler   regards   ofstream   as   basibasic_ostream,   not   ostream.  
  When   it   sees   "outfile<<cpxVale<<endl;",   the   "<<"   provided   by   complex   class   will   be   called,   while   when   it   sees   "cout<<cpxVale<<endl;",   your   function   is   better   than   std's.Top

2 楼mayflowers(黯然神伤)回复于 2005-08-04 22:56:27 得分 0

BTW:  
   
  ofstream&   operator<<(ofstream&   ofs,   const   COMPLEX&   cpValue)  
  {  
      ofs   <<   abs(cpValue)   <<   "∠"   <<   MakeAngleFromRadian(   arg(cpValue)   );  
      return   ofs;  
  }  
   
  can   bring   you   the   right   result.Top

3 楼fengchang(everate)回复于 2005-08-05 09:20:36 得分 0

typedef   basic_ostream<char>   ostream,不就是表明ostream是basic_ostream<char>的一个别名吗?Top

4 楼mayflowers(黯然神伤)回复于 2005-08-05 11:12:20 得分 39

非常抱歉,上面的回答是完全错误的。  
  而且在自己没有完全确定的时候回答这个问题更加不好。sorry。  
   
  According   to   C++   Primer   3rd   P424   &   P435:  
  函数模版推导四个步骤:  
  1.   生成候选参数集;  
  2.   生成可行参数集;  
  3.   对类型转换划分等级;  
  3.b.   如果调用是二义的,则从可行函数集中去掉函数模版实例;  
  4.   只考虑可行函数集中的普通函数。  
   
  在你的代码中,你的函数是一个普通函数(不是模版的特化)。  
   
  如你所说,这两个函数在3.b时是一样的(需要同样的类型转换),所以应该选择普通函数,也就是你的函数。  
   
  但是这个问题在VC   6.0中处理的非常怪异:  
  template   <class   T>  
  void   func(T   t)  
  {  
  }  
   
  void   func(int   i)  
  {  
  }  
   
  int   main()  
  {  
      func((int)   1);     //   call   func(int   i);  
      func(0.0);   //   call   template   function;  
      return   0;  
  }  
   
  这一点是正确的,但是涉及到继承的时候,就会出现你的结果:  
   
  class   A   {};   class   B   :   public   A   {};  
   
  void   func(A   a)  
  {  
  }  
   
  int   main()  
  {  
      B   b;  
   
      func(b);     //   call   template   function,   not   func(A   a);  
   
      return   0;  
  }  
   
  这个不符合C++的规范——要求优先选择普通函数。  
   
  我在redhat下用g++3.2.2运行你的代码,可以得到你想要的结果。调用的是你的普通函数。  
   
  所以,如果没有疏漏的话,这个时vc的bug。  
   
  btw:   我的是vc6.0   +   sp5。Top

5 楼fangrk(加把油,伙计!)回复于 2005-08-05 12:36:07 得分 1

.net2003编译通过,bcb6编译错误,标准库中已经有了complex的输出函数。  
   
  方法1:不要重载标准库中的输出函数  
  #include   <fstream>  
  #include   <iostream>  
  #include   <complex>  
  using   namespace   std;  
   
  typedef   complex<double>   COMPLEX;  
  const   double   PI   =   3.1415926;  
  const   int   PIAngle   =   180;  
  static   double   MakeAngleFromRadian(double   dRadian)  
  {  
  double   dAngle   =   dRadian/PI*PIAngle;  
  if   (dAngle<-PIAngle)  
  dAngle   +=   2*PIAngle;  
  else   if   (dAngle>PIAngle)  
  dAngle   -=   2*PIAngle;  
  return   dAngle;//返回值的范围在[-180,180]之间;  
  }  
  ostream&   output(ostream&   os,const   COMPLEX&   cpValue)  
  {  
      os<<abs(cpValue)<<"∠"<<MakeAngleFromRadian(arg(cpValue));  
      return   os;  
  }  
   
  int   main()  
  {    
    COMPLEX   cpxVale(1,1);  
  ofstream   outfile("a.txt");  
  output(cout,cpxVale);  
  output(outfile,cpxVale);  
   
  }    
   
  方法2:采用名字空间  
  #include     <fstream>  
  #include     <iostream>  
  #include   <complex>  
  using   namespace   std;  
   
  namespace   MyTest  
  {  
  typedef   complex<double>   COMPLEX;  
  const   double   PI   =   3.1415926;  
  const   int   PIAngle   =   180;  
  static   double   MakeAngleFromRadian(double   dRadian)  
  {  
  double   dAngle   =   dRadian/PI*PIAngle;  
  if   (dAngle<-PIAngle)  
  dAngle   +=   2*PIAngle;  
  else   if   (dAngle>PIAngle)  
  dAngle   -=   2*PIAngle;  
  return   dAngle;//返回值的范围在[-180,180]之间;  
  }  
  ostream&   operator<<(ostream&   os,const   COMPLEX&   cpValue)  
  {  
      os<<abs(cpValue)<<"∠"<<MakeAngleFromRadian(arg(cpValue));  
      return   os;  
  }  
  }  
  int   main()  
  {    
    MyTest::COMPLEX   cpxVale(1,1);  
  ofstream   outfile("a.txt");  
  using   MyTest::operator<<;//优先考虑MyTest中的输出函数  
  cout<<cpxVale;  
  outfile<<cpxVale;  
  }Top

相关问题

  • 关于重载操作符,请帮忙
  • 操作符重载问题,请帮忙
  • 操作符“<<”重载出问题了,大家帮我看看怎么回事。。。
  • 操作符重载
  • 操作符重载
  • 操作符重载
  • 关于操作符重载。
  • 有关操作符重载
  • 怎样重载 = 操作符?
  • 关于“=”操作符重载问题。很急!有经验的朋友帮忙!!

关键词

  • c++
  • 函数
  • 模版
  • 普通
  • basic
  • template
  • vc
  • piangle
  • dangle
  • dradian

得分解答快速导航

  • 帖主:fengchang
  • mayflowers
  • fangrk

相关链接

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

广告也精彩

反馈

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