LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 970|回复: 7

有关运算符重载的问题

[复制链接]
发表于 2003-7-18 22:16:24 | 显示全部楼层 |阅读模式
这是书上的一个例题

  1. //HugeInt.h
  2. #ifndef HUGEINT_H
  3. #define HUGEINT_H

  4. #include<iostream>
  5. using namespace std;
  6.         
  7. class HugeInt   {
  8.         friend ostream &operator<<( ostream &, HugeInt & );
  9. public:
  10.         HugeInt( long = 0 );
  11.         HugeInt( const char *);
  12.         HugeInt operator+( HugeInt & );
  13.         HugeInt operator+( int );
  14.         HugeInt operator+( const char * );
  15. private:
  16.         short integer[30];
  17. };      
  18.         
  19. #endif  
复制代码

  1. //HugeInt.cpp
  2. #include"HugeInt.h"
  3.         
  4. HugeInt::HugeInt( long val )
  5. {               
  6.         int i;
  7.         for ( i = 0; i <=29; i++ )
  8.                 integer[ i ] = val % 10;

  9.         for ( i = 29; val != 0 && i >=0; i-- ){
  10.                 integer[ i ] = val % 10;
  11.                 val /= 10;
  12.         }
  13. }      
  14.         
  15. HugeInt::HugeInt( const char * string)
  16. {               
  17.         int i, j;      
  18.         for ( i = 0; i <= 29; i++ )
  19.                 integer[ i ] = 0;
  20.                
  21.         for ( i = 30 - strlen( string ), j = 0; i <= 29; i++, j++)
  22.                 integer[ i ] = string[ j ] - '0';
  23. }      
  24. HugeInt HugeInt::operator+( HugeInt &op2 )
  25. {
  26.         HugeInt temp;
  27.         int carry = 0;
  28.         for ( int i = 29; i >= 0; i-- ) {
  29.                 temp.integer[ i ] = integer[ i ] + op2.integer[ i ] + carry;
  30.                 if ( temp.integer[ i ] > 9 ) {
  31.                         temp.integer[ i ] %= 10;
  32.                         carry = 1;
  33.                 }
  34.                 else
  35.                         carry = 0;
  36.         }
  37.         return temp;
  38. }

  39. HugeInt HugeInt::operator+( int op2 )
  40. { return *this + HugeInt( op2 );}

  41. HugeInt HugeInt::operator+( const char * op2 )
  42. { return *this + HugeInt ( op2);}

  43. ostream & operator<<( ostream & output, HugeInt &num )
  44. {      
  45.         int i;
  46.         
  47.         for ( i = 0; ( num.integer[ i ] == 0 ) && ( i <=29 ); i++)
  48.                 ;
  49.         if ( i == 30 )  
  50.                 output << 0;
  51.         else   
  52.                 for ( ; i <= 29; i++ )
  53.                         output << num.integer[ i ];
  54.         return output;
  55. }   
复制代码

  1. //main.cpp
  2. #include"HugeInt.h"
  3. #include<iostream>
  4. using namespace std;
  5.                
  6. int main()      
  7. {
  8.         HugeInt n1( 1234567890 ),
  9.                 n2( "9999999999999999" ),
  10.                 n3( "1" ),
  11.                 n4;
  12.         cout << " n1 is " << n1 << "\nn2 is " << n2
  13.              << " \nn2 is " << " \nn3 is " << n3
  14.              << " \nn4 is " << " \n\n";
  15.                         
  16.         n4 = n1 + n2;   
  17.         cout << n1 << " + " << n2 << " = " << n4 << "\n\n";
  18.                
  19.         cout << n2 << " + " << n3 << "\n= " << ( n2 + n3 )
  20.              << "\n\n";
  21.         
  22.         n4 = n1 + HugeInt( 9L );
  23.         cout << n1 << " + " << 9 << " = " << n4 << endl;

  24.         return 0;
  25. }

复制代码


#gcc -S HugeInt.cpp
HugeInt.cpp: In member function `HugeInt HugeInt:perator+(int)':
HugeInt.cpp:42: error: no match for `HugeInt& + HugeInt' operator
HugeInt.cpp:26: error: candidates are: HugeInt HugeInt:perator+(HugeInt&)
HugeInt.cpp:42: error:                 HugeInt HugeInt:perator+(int)
HugeInt.h:14: error:                 HugeInt HugeInt:perator+(const char*)
HugeInt.cpp: In member function `HugeInt HugeInt:perator+(const char*)':
HugeInt.cpp:45: error: no match for `HugeInt& + HugeInt' operator
HugeInt.cpp:26: error: candidates are: HugeInt HugeInt:perator+(HugeInt&)
HugeInt.cpp:42: error:                 HugeInt HugeInt:perator+(int)
HugeInt.cpp:45: error:                 HugeInt HugeInt:perator+(const char*)
#gcc -S main.cpp
main.cpp: In function `int main()':
main.cpp:19: error: no match for `std::basic_ostream<char,
   std::char_traits<char> >& << HugeInt' operator
/usr/include/c++/3.3/bits/ostream.tcc:63: error: candidates are:
   std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT,
   _Traits>:perator<<(std::basic_ostream<_CharT,
   _Traits>&(*)(std::basic_ostream<_CharT, _Traits>&)) [with _CharT = char,
   _Traits = std::char_traits<char>]
/usr/include/c++/3.3/bits/ostream.tcc:85: error:                 
   std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT,
   _Traits>:perator<<(std::basic_ios<_CharT,
   _Traits>&(*)(std::basic_ios<_CharT, _Traits>&)) [with _CharT = char, _Traits
   = std::char_traits<char>]
/usr/include/c++/3.3/bits/ostream.tcc:107: error:                 
   std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT,
   _Traits>::operator<<(std::ios_base&(*)(std::ios_base&)) [with _CharT = char,
   _Traits = std::char_traits<char>]
/usr/include/c++/3.3/bits/ostream.tcc:179: error:                 
   std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT,
   _Traits>::operator<<(long int) [with _CharT = char, _Traits =
   std::char_traits<char>]/usr/include/c++/3.3/bits/ostream.tcc:216: error:                 
   std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT,
   _Traits>::operator<<(long unsigned int) [with _CharT = char, _Traits =
   std::char_traits<char>]
/usr/include/c++/3.3/bits/ostream.tcc:154: error:                 
   std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT,
   _Traits>::operator<<(bool) [with _CharT = char, _Traits =
   std::char_traits<char>]
/usr/include/c++/3.3/ostream:178: error:                 
   std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT,
   _Traits>::operator<<(short int) [with _CharT = char, _Traits =
   std::char_traits<char>]
/usr/include/c++/3.3/ostream:189: error:                 
   std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT,
   _Traits>::operator<<(short unsigned int) [with _CharT = char, _Traits =
   std::char_traits<char>]
/usr/include/c++/3.3/ostream:193: error:                 
   std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT,
   _Traits>::operator<<(int) [with _CharT = char, _Traits =
   std::char_traits<char>]
/usr/include/c++/3.3/ostream:193: error:                 
   std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT,
   _Traits>::operator<<(int) [with _CharT = char, _Traits =
   std::char_traits<char>]
/usr/include/c++/3.3/ostream:204: error:                 
   std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT,
   _Traits>::operator<<(unsigned int) [with _CharT = char, _Traits =
   std::char_traits<char>]
/usr/include/c++/3.3/bits/ostream.tcc:242: error:                 
   std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT,
   _Traits>::operator<<(long long int) [with _CharT = char, _Traits =
   std::char_traits<char>]
/usr/include/c++/3.3/bits/ostream.tcc:280: error:                 
   std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT,
   _Traits>::operator<<(long long unsigned int) [with _CharT = char, _Traits =
   std::char_traits<char>]
/usr/include/c++/3.3/bits/ostream.tcc:306: error:                 
   std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT,
   _Traits>::operator<<(double) [with _CharT = char, _Traits =
   std::char_traits<char>]
/usr/include/c++/3.3/ostream:219: error:                 
   std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT,
   _Traits>::operator<<(float) [with _CharT = char, _Traits =
   std::char_traits<char>]
/usr/include/c++/3.3/bits/ostream.tcc:331: error:                 
   std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT,
   _Traits>::operator<<(long double) [with _CharT = char, _Traits =
   std::char_traits<char>]
/usr/include/c++/3.3/bits/ostream.tcc:356: error:                 
   std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT,
   _Traits>::operator<<(const void*) [with _CharT = char, _Traits =
   std::char_traits<char>]
/usr/include/c++/3.3/bits/ostream.tcc:128: error:                 
   std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT,
   _Traits>::operator<<(std::basic_streambuf<_CharT, _Traits>*) [with _CharT =
   char, _Traits = std::char_traits<char>]
HugeInt.h:8: error:                 std::ostream& operator<<(std::ostream&,
   HugeInt&)
/usr/include/c++/3.3/ostream:491: error:                 
   std::basic_ostream<char, _Traits>& std::operator<<(std::basic_ostream<char,
   _Traits>&, const unsigned char*) [with _Traits = std::char_traits<char>]
/usr/include/c++/3.3/ostream:486: error:                 
   std::basic_ostream<char, _Traits>& std::operator<<(std::basic_ostream<char,
   _Traits>&, const signed char*) [with _Traits = std::char_traits<char>]
/usr/include/c++/3.3/bits/ostream.tcc:630: error:                 
   std::basic_ostream<char, _Traits>& std::operator<<(std::basic_ostream<char,
   _Traits>&, const char*) [with _Traits = std::char_traits<char>]
/usr/include/c++/3.3/bits/ostream.tcc:580: error:                 
   std::basic_ostream<_CharT, _Traits>&
   std::operator<<(std::basic_ostream<_CharT, _Traits>&, const char*) [with
   _CharT = char, _Traits = std::char_traits<char>]
/usr/include/c++/3.3/ostream:452: error:                 
   std::basic_ostream<char, _Traits>& std::operator<<(std::basic_ostream<char,
   _Traits>&, unsigned char) [with _Traits = std::char_traits<char>]
/usr/include/c++/3.3/ostream:447: error:                 
   std::basic_ostream<char, _Traits>& std::operator<<(std::basic_ostream<char,
   _Traits>&, signed char) [with _Traits = std::char_traits<char>]
/usr/include/c++/3.3/bits/ostream.tcc:508: error:                 
   std::basic_ostream<char, _Traits>& std::operator<<(std::basic_ostream<char,
   _Traits>&, char) [with _Traits = std::char_traits<char>]
/usr/include/c++/3.3/ostream:436: error:                 
   std::basic_ostream<_CharT, _Traits>&
   std::operator<<(std::basic_ostream<_CharT, _Traits>&, char) [with _CharT =
   char, _Traits = std::char_traits<char>]
main.cpp:21: error: no match for `HugeInt& + HugeInt' operator
HugeInt.h:12: error: candidates are: HugeInt HugeInt::operator+(HugeInt&)
发表于 2003-7-18 22:48:33 | 显示全部楼层
哇!!!这么多错误,只要把关键的几行贴出来就行了。
 楼主| 发表于 2003-7-19 00:04:42 | 显示全部楼层
其实关键的就这么几行,也可以一眼看出的:
HugeInt.cpp: In member function `HugeInt HugeInt:perator+(int)':
HugeInt.cpp:42: error: no match for `HugeInt& + HugeInt' operator
HugeInt.cpp:26: error: candidates are: HugeInt HugeInt:perator+(HugeInt&)
HugeInt.cpp:42: error: HugeInt HugeInt:perator+(int)
HugeInt.h:14: error: HugeInt HugeInt:perator+(const char*)
HugeInt.cpp: In member function `HugeInt HugeInt:perator+(const char*)':
HugeInt.cpp:45: error: no match for `HugeInt& + HugeInt' operator
HugeInt.cpp:26: error: candidates are: HugeInt HugeInt:perator+(HugeInt&)
HugeInt.cpp:42: error: HugeInt HugeInt:perator+(int)
HugeInt.cpp:45: error: HugeInt HugeInt:perator+(const char*)
main.cpp:21: error: no match for `HugeInt& + HugeInt' operator
HugeInt.h:12: error: candidates are: HugeInt HugeInt:perator+(HugeInt&)

好像是说对“HugeInt & + HugeInt”中的“+”没有重载过。
但是我在
HugeInt HugeInt:perator+( const char * op2 )
{ return *this + HugeInt ( op2);}

难道这里的*this + HugeInt,是匹配HugeInt & + HugeInt,而不HugeInt  + HugeInt?这两者有什么区别?
发表于 2003-7-19 09:29:48 | 显示全部楼层
呵呵,C++在语法检查确实比C要严格。应该说这是一件好事。
我注意到你的类似于return *this + HugeInt ( op2);的写法,这种写法与HugeInt temp=HugeInt(op2); return *this + temp;是不同的。因为HugeInt(op2)生成的是一个临时变量,这个临时变量是由编译器生成的,因而只能访问,不能更改,它的类型就不是一个简单的HugeInt,而是const HugeInt。因此,把重载的运算符+中的声明改成HugeInt operator+( const HugeInt & );就行了。 同理,在main.cpp中的cout << n2 << " + " << n3 << "\n= " << ( n2 + n3 )<< "\n\n";也是由于(n2 + n3)要由编译器生成一个const HugeInt的临时变量,因而运算符重载的<<声明中,也要加上const,变成friend ostream &operator<<( ostream &, const HugeInt & );。
发表于 2003-7-19 09:32:12 | 显示全部楼层
修改后编译通过的程序。

  1. //HugeInt.h
  2. #ifndef HUGEINT_H
  3. #define HUGEINT_H
  4. #include<iostream>
  5. using namespace std;
  6.         
  7. class HugeInt   {
  8.         friend ostream &operator<<( ostream &, const HugeInt & );
  9. public:
  10.         HugeInt( long = 0 );
  11.         HugeInt( const char *);
  12.         HugeInt operator+( const HugeInt & );
  13.         HugeInt operator+( int );
  14.         HugeInt operator+( const char * );
  15. private:
  16.         short integer[30];
  17. };      
  18.         
  19. #endif  
复制代码

  1. //HugeInt.cpp
  2. #include"hugeint.h"
  3.         
  4. HugeInt::HugeInt( long val )
  5. {               
  6.         int i;
  7.         for ( i = 0; i <=29; i++ )
  8.                 integer[ i ] = val % 10;
  9.         for ( i = 29; val != 0 && i >=0; i-- ){
  10.                 integer[ i ] = val % 10;
  11.                 val /= 10;
  12.         }
  13. }      
  14.         
  15. HugeInt::HugeInt( const char * string)
  16. {               
  17.         int i, j;      
  18.         for ( i = 0; i <= 29; i++ )
  19.                 integer[ i ] = 0;
  20.                
  21.         for ( i = 30 - strlen( string ), j = 0; i <= 29; i++, j++)
  22.                 integer[ i ] = string[ j ] - '0';
  23. }      
  24. HugeInt HugeInt:: operator+(const HugeInt &op2 )
  25. {
  26.         HugeInt temp;
  27.         int carry = 0;
  28.         for ( int i = 29; i >= 0; i-- ) {
  29.                 temp.integer[ i ] = integer[ i ] + op2.integer[ i ] + carry;
  30.                 if ( temp.integer[ i ] > 9 ) {
  31.                         temp.integer[ i ] %= 10;
  32.                         carry = 1;
  33.                 }
  34.                 else
  35.                         carry = 0;
  36.         }
  37.         return temp;
  38. }
  39. HugeInt HugeInt:: operator+( int op2 )
  40. { return *this + HugeInt( op2 );}
  41. HugeInt HugeInt:: operator+( const char * op2 )
  42. { return *this + HugeInt ( op2);}
  43. ostream & operator<<( ostream & output, const HugeInt &num )
  44. {      
  45.         int i;
  46.         
  47.         for ( i = 0; ( num.integer[ i ] == 0 ) && ( i <=29 ); i++)
  48.                 ;
  49.         if ( i == 30 )  
  50.                 output << 0;
  51.         else   
  52.                 for ( ; i <= 29; i++ )
  53.                         output << num.integer[ i ];
  54.         return output;
  55. }   
复制代码

  1. //main.cpp
  2. #include"hugeint.h"
  3. #include<iostream>
  4. using namespace std;
  5.                
  6. int main()      
  7. {
  8.         HugeInt n1( 1234567890 ),
  9.                 n2( "9999999999999999" ),
  10.                 n3( "1" ),
  11.                 n4;
  12.         cout << " n1 is " << n1 << "\nn2 is " << n2
  13.              << " \nn2 is " << " \nn3 is " << n3
  14.              << " \nn4 is " << " \n\n";
  15.                         
  16.         n4 = n1 + n2;   
  17.         cout << n1 << " + " << n2 << " = " << n4 << "\n\n";
  18.                
  19.         cout << n2 << " + " << n3 << "\n= " << ( n2 + n3 )
  20.              << "\n\n";
  21.         
  22.         n4 = n1 + HugeInt( 9L );
  23.         cout << n1 << " + " << 9 << " = " << n4 << endl;
  24.         return 0;
  25. }
复制代码
 楼主| 发表于 2003-7-19 11:00:59 | 显示全部楼层
谢谢

还想问一个问题,怎么样让运算符具有交换性?
在这里HugeInt + int 是可以的。但是int + HugeInt又得另外重载?
为什么他不通过构造函数自动把int转化成HugeInt然后匹配HugeInt + HugeInt?
还有char * + HugeInt也是的。
发表于 2003-7-20 00:39:16 | 显示全部楼层
operator + (&b)
a+b
相当于a.operator + (b)
对应的b+a相当于b.operator +(a);
因为没有所以需要再重载一次

可能有其它方法不用的吧
但是忘记了  以后想起来再写上来
 楼主| 发表于 2003-7-20 22:29:05 | 显示全部楼层
最初由 无双 发表
operator + (&b)
a+b
相当于a.operator + (b)
对应的b+a相当于b.operator +(a);
因为没有所以需要再重载一次


但是,如果a类中有构造函数把b类转化成a类
那么b.operator + ( a );
为什么不变成a(b).operator + ( a );呢?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表