LinuxSir.cn,穿越时空的Linuxsir!

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

模板类与友元函数, 重载运算符<<的问题

[复制链接]
发表于 2007-8-27 23:02:22 | 显示全部楼层 |阅读模式
链接提示有问题,请教

complex.h
----------------------------

  1. #ifndef _COMPLEX_HEADER_
  2. #define _COMPLEX_HEADER_

  3. #include <iostream>

  4. template<class Type>
  5. class complex
  6. {
  7.         friend std::ostream& operator << (std::ostream& out, const complex<Type>& complex_num);

  8.     private:
  9.                 Type real;
  10.                 Type image;
  11.         public:
  12.                 complex();
  13.                 complex(complex& number);
  14.                 complex(Type real, Type image);
  15.                 void operator = (const complex& in_number);
  16.                
  17.         public:
  18.                 complex& operator + (const complex& add) const;
  19.                 Type get_real() const { return real; } ;
  20.                 Type get_image() const { return image; } ;
  21.                
  22. };

  23. template<class Type>
  24. std::ostream&  operator << (std::ostream& os, const complex<Type>& complex_num);

  25. template<class Type>
  26. complex<Type>::complex()
  27. {
  28.         real = 0;
  29.         image = 0;
  30. }

  31. template<class Type>
  32. complex<Type>::complex(complex<Type>& number)
  33. {
  34.         real = number.real;
  35.         image = number.image;
  36. }

  37. template<class Type>
  38. complex<Type>::complex(Type in_real, Type in_image)
  39. {
  40.         real = in_real;
  41.         image = in_image;
  42. }

  43. template<class Type>
  44. complex<Type>& complex<Type>::operator + (const complex<Type>& add) const
  45. {
  46.         complex<Type> result;
  47.         result.real = real + add.real;
  48.         result.image = image + add.image;

  49.         return result;
  50. }


  51. template<class Type>
  52. void complex<Type>::operator = (const complex<Type>& in_number)
  53. {
  54.         real = in_number.real;
  55.         image = in_number.image;
  56. }


  57. template<class Type>
  58. std::ostream&  operator <<  ( std::ostream& os, const complex<Type>& complex_num)
  59. {
  60.         os<<complex_num.real;
  61.         if (complex_num.image > 0) os<<'+';
  62.         if (complex_num.image != 0) os<<complex_num.image<<"i";
  63.         return os;
  64. }

  65. #endif //_COMPLEX_HEADER_
复制代码


complex.cpp
------------------------

  1. #include <iostream>
  2. #include "complex.h"

  3. int main()
  4. {
  5.         complex<int> a(3,5);
  6.         complex<int> b(7,8);
  7.         complex<int> c;
  8.        
  9.         c = a + b;

  10.         std::cout<<"c="<<c.get_real()<<"+"<<c.get_image()<<"i"<<std::endl;

  11.         std::cout<<c;

  12.         return 0;
  13. }
复制代码


编译输出:
-----------------------------

  1. waterzh@bing ~ $ g++ complex.cpp
  2. complex.h:9: 警告:友元声明 ‘std::ostream& operator<<(std::ostream&, const complex<Type>&)’ 声明了一个非模板函数
  3. complex.h:9: 警告:(如果这不是您原来的想法,请确定此函数模板已经声明过,并在这里的函数名后面添加 <>) -Wno-non-template-friend 禁用此警告
  4. complex.h: In member function ‘complex<Type>& complex<Type>::operator+(const complex<Type>&) const [with Type = int]’:
  5. complex.cpp:10:   instantiated from here
  6. complex.h:54: 警告:返回了对局部变量的 ‘result’ 的引用
  7. /tmp/ccQnC6Iu.o:在函数‘main’中:
  8. complex.cpp:(.text+0x16c):对‘operator<<(std::basic_ostream<char, std::char_traits<char> >&, complex<int> const&)’未定义的引用
  9. collect2: ld 返回 1

复制代码
发表于 2007-8-28 00:08:56 | 显示全部楼层
这是在做什么?
  1. template<class Type>
  2. std::ostream&  operator << (std::ostream& os, const complex<Type>& complex_num);
复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-8-28 22:15:34 | 显示全部楼层
Post by rickxbx
这是在做什么?

  1. template<class Type>
  2. std::ostream&  operator << (std::ostream& os, const complex<Type>& complex_num);
复制代码


定义函数<<,有没有这两行结果都一样。
ld返回结果是连接类型没有匹配上,找不到

  1. operator<<(std::basic_ostream<char, std::char_traits<char> >&, [b]complex<int>[/b] const&)
复制代码

请明示
回复 支持 反对

使用道具 举报

发表于 2007-8-29 02:24:38 | 显示全部楼层
You should declare the friend template function before declaring it as a friend of the class, which leads to actually 3 steps for a friend template function declaration:

  1. template <class Type> class complex;
  2. template<class Type>
  3. std::ostream&  operator << (std::ostream& os, const complex<Type>& complex_num);

  4. template<class Type>
  5. class complex
  6. {
  7.         friend std::ostream& operator << <>(std::ostream& out, const complex<Type>& complex_num);
  8. };
复制代码


Note that there is a pair of angle brackets ('<>') after '<<'.
More information can be found in this link
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-8-29 23:29:33 | 显示全部楼层
试过把<< 的重载声明放在类的实现前,编译提示<<函数中complex不是一个有效的类型,所以就把<<的声明放在类的实现后面, 但没有想到把complex的声明放在<< 前。

等错误转变成一个链接错误的时候,就错失方向了。一念之差。

谢谢。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

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