【问题标题】:C++ operator << print object addressC++ 运算符 << 打印对象地址
【发布时间】:2012-04-03 14:06:25
【问题描述】:

是否可以有一个重载 ostream 运算符

class MyCls {
      friend ostream& operator << (ostream& o, const MyCls& c) { return o << "MyClass\n";  }
      friend ostream& operator << (ostream& o, const MyCls *c) { return operator<<(o, *c); }
};
MyCls a, b;
std::cout << a << b;

预期输出:

(0x12345678) MyClass
(0x23456789) MyClass

有什么解决方法吗?

[编辑]

场景

我跳过了很多有关 MyCls 的细节,以使问题看起来很简单。该类实际上具有指向其他类的指针向量。这些类也以类似的方式重载了 ostream 运算符。所以我的主要目标是显示哪些对象包含在哪些容器中。

class MyClsB {};
class MyCls {std::vector<MyClsB *> containers; std::string attrA;};

class Printer() {
    void operator() (const T& arg) { os << arg;}
    void operator() (T *arg) { os << *arg; }
    }

int main(int c, char** a) {
    std::vector<MyCls *> v;
    //version 1
    for (int i = 0; i < v.size(); i++) std::cout << v[i] << "\n";
        //version 2
        for_each(v.begin(), v.end(); Printer(std::cout));
        return 0;
}

预期输出

(0x12345678) MyCls: attrA = v1
(0x1234abcd) MyClsB
(0x1234defg) MyClsB
(0x23456789) MyCls: attrA = v2
(0x2345abcd) MyClsB
...

平台

  • Win 7x64:VS2010 express
  • Linux : gcc 4.4.5

[编辑 1]:我尝试了 Benjamin 的方法,它只是给我带来了分段错误。添加一些调试打印表明 Benjamin 的方法只是进入了无限循环。

[编辑 2]:对于 Jerry 的建议,我的编译器抱怨“从类型‘const MyCls*’到类型‘void*’的静态转换无效”(gcc 4.4.5)

[编辑 3]:删除 operator

为什么我声明指针版本是为了简化调用语句。而不是

std::cout << *p2Obj

只是

std::cout << p2Obj

另外,我有一个仿函数对象,用于与 for_each() 调用 my previous question 结合使用

【问题讨论】:

  • 只打印重载运算符中的指针不起作用?究竟是什么问题?
  • 你还有这个功能吗? friend ostream&amp; operator &lt;&lt; (ostream&amp; o, const MyCls *c) { return operator&lt;&lt;(o, *c); } -- 删除那个。这就是导致你无限循环的原因。您有一个接受引用的函数,它调用接受指针的函数,该函数正在调用接受引用的函数……无穷无尽。如果您只使用我提供的版本,即带有引用的版本,它将依赖于打印指针的默认行为,即仅打印它所拥有的地址。
  • 另外,如果您将 static_cast&lt;void *&gt; 更改为 static_cast&lt;const void*&gt;,您可以让 Jerry 的版本正常工作

标签: c++ operator-overloading memory-address


【解决方案1】:

我认为我所做的工作与迄今为止在答案中看到的略有不同——我会在打印之前明确地将地址转换为void *

std::ostream &operator<<(std::ostream &os, MyCls const &object) { 
    return os << "(" << static_cast<void const *>(&object) << ") MyClass\n";
}

我通常不喜欢强制转换,但在这种情况下,我认为值得明确说明您的意图是打印出地址,这样就不会有人将其误认为是错误/事故。

【讨论】:

  • std::ostream &amp; osstatic_cast&lt;const void *&gt; 没有?
  • @BenjaminLindley:是的,两者都是。
【解决方案2】:

当然

ostream& operator << (ostream& o, const MyCls& c)
{
    return o << "(" << &c << ") MyClass\n";
}

【讨论】:

    【解决方案3】:

    您的示例代码有很多问题,但这很容易做到,不需要朋友:

    #include <iostream>
    
    class MyCls {
    };
    
    std::ostream& operator<<(std::ostream& out, MyCls& instance) {
      return out << "MyCls" << &instance;
    }
    

    足够了。

    【讨论】:

      【解决方案4】:

      为什么不简单:

      class MyCls {
         friend ostream& operator << (ostream& o, const MyCls& c) 
                        { return o << "MyClass\n" << &c;  }
      };
      

      用法:

      MyCls a, b;
      std::cout << a << b;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-02-10
        • 1970-01-01
        • 2011-05-31
        • 2022-01-23
        • 2013-07-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多