LinuxSir.cn,穿越时空的Linuxsir!

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

C++中<<和>>的重载问题

[复制链接]
发表于 2005-9-11 20:26:33 | 显示全部楼层 |阅读模式
C++中的<<和>>是否只能用友员函数重载,
我的代码写成这样:
#include <iostream>
using namespace std;

class X {
    public:
        X(int i = 0);
        ~X();

        ostream& operator << (ostream&);

    private:
        int   x;

};

X::X(int i)
    :x(i)
{
}

X::~X()
{
}

ostream& X:perator << (ostream& os)
{
    os << x;

    return os;
}



int main()
{
    X         x(10);

    cout << x << endl;

    return 0;
}
编译出错:
t7.cpp:44: error: no match for 'operator<<' in 'std::cout << x'

如果改成friend 函数:
#include <iostream>
using namespace std;

class X {
    public:
        X(int i = 0);
        ~X();

        friend ostream& operator << (ostream&, const X&);

    private:
        int   x;

};

X::X(int i)
    :x(i)
{
}

X::~X()
{
}

ostream& operator << (ostream& os, const X& x)
{
    os << x.x;

    return os;
}



int main()
{
    X         x(10);

    cout << x << endl;

    return 0;
}

这样编译运行成功.

是不是由于这个原因呀:

语句:
cout<<x<<endl;
是采用
operator << (ostream&, X)
的形式调用的.

而X中的成员函数
operator << (ostream&)
会展开成
operator << (*this, ostream)
的形式.

所以代码1在找不到合适的函数, 就报错.
发表于 2005-9-11 22:03:31 | 显示全部楼层
我想是这样的.

  1. #include <stdio.h>

  2. class X
  3. {
  4.         public:
  5.                 X(int i)
  6.                 {
  7.                         _i = i;
  8.                 }
  9.                
  10.                 int operator + (int v)
  11.                 {
  12.                         return _i + v;
  13.                 }
  14.         private:
  15.                 int _i;
  16.         public:
  17.                 int get_i()
  18.                 {
  19.                         return _i;
  20.                 }
  21. };

  22. int operator - (X &a, int v)
  23. {
  24.         return a.get_i() - v;
  25. }

  26. int main()
  27. {
  28.         X x(10);
  29.         printf("%d\n", x + 5);
  30.         printf("%d\n", x - 5);
  31. }
复制代码
回复 支持 反对

使用道具 举报

发表于 2005-9-11 22:36:09 | 显示全部楼层
你的成员函数应该会展开成

  1. operator<<(cout, *this);  // *this作为最后一个参数
复制代码

因此没有机会被调用。

要想用也行:

  1. x.operator<<(cout);
复制代码

而用

  1. cout << x;
复制代码

不会调用成员函数,因为这个调用的是

  1. operator<<(cout, x);
复制代码

是全局函数
运算符重载一般不作为成员函数,以方便类型转换问题。楼上的operator+()就不太好的说。
回复 支持 反对

使用道具 举报

发表于 2005-9-11 22:41:58 | 显示全部楼层
Post by JBug

是不是由于这个原因呀:

语句:
cout<<x<<endl;
是采用
operator << (ostream&, X)
的形式调用的.

是的.

而X中的成员函数
operator << (ostream&)
会展开成
operator << (*this, ostream)
的形式.

这个就不一定了,这个与编译器有关,gcc确实是这么做的(不过第一个参数是this,而不是*this),下面的例子:

  1. [rick@Fedora-Core test]$ cat test.cc
  2. #include <iostream>
  3. #include <fstream>

  4. using namespace std;

  5. class C
  6. {
  7. public:
  8.         void f()
  9.         {
  10.                 printf("haha\n");
  11.         }
  12. };

  13. int main(int argc,char** argv)
  14. {
  15.         C c;
  16.         c.f();

  17.         return 0;
  18. }
复制代码

  1. 080486ae <main>:
  2. 80486ae:       55                      push   %ebp
  3. 80486af:       89 e5                   mov    %esp,%ebp
  4. 80486b1:       83 ec 08                sub    $0x8,%esp
  5. 80486b4:       83 e4 f0                and    $0xfffffff0,%esp
  6. 80486b7:       b8 00 00 00 00          mov    $0x0,%eax
  7. 80486bc:       83 c0 0f                add    $0xf,%eax
  8. 80486bf:       83 c0 0f                add    $0xf,%eax
  9. 80486c2:       c1 e8 04                shr    $0x4,%eax
  10. 80486c5:       c1 e0 04                shl    $0x4,%eax
  11. 80486c8:       29 c4                   sub    %eax,%esp
  12. 80486ca:       83 ec 0c                sub    $0xc,%esp
  13. 80486cd:       8d 45 ff                lea    0xffffffff(%ebp),%eax
  14. 80486d0:       50                      push   %eax
  15. 80486d1:       e8 7a 00 00 00          call   8048750 <_ZN1C1fEv>
  16. 80486d6:       83 c4 10                add    $0x10,%esp
  17. 80486d9:       b8 00 00 00 00          mov    $0x0,%eax
  18. 80486de:       c9                      leave
  19. 80486df:       c3                      ret
复制代码

以前看过VC生成的汇编,却不是这个样子的.
回复 支持 反对

使用道具 举报

发表于 2005-9-11 22:45:44 | 显示全部楼层
偶觉得<<thinking in C++>>里的"Operator Overloading"一章讲得很清楚.
回复 支持 反对

使用道具 举报

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

本版积分规则

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