【问题标题】:How to overload the << operator如何重载 << 运算符
【发布时间】:2017-04-20 21:54:55
【问题描述】:

我正在尝试使用代码重载

inline ostream& operator<< (ostream& out, Node& n){n.print(out); return out;}

而我调用的打印函数只是

void Node::print(ostream& out){
    out<< freq << "  " << input<<"  " << Left<< "  " << Right<< endl;
}

当我调用 print 函数时,Left 和 right 都是以十六进制打印的指针。但是当我使用 当我尝试打印它时,我正在打印一个 Node*,我不知道这是否与它有关。

感谢您的帮助。

【问题讨论】:

  • 仅供参考,Node 应该由 constant 引用传递,例如const Node&amp; n。另外,将Node::print 更改为常量方法:void Node::print(ostream&amp; out) const
  • 真正的问题是什么?

标签: c++ printing overloading


【解决方案1】:

当我尝试打印它时,我正在打印一个 Node*,我不知道这是否与它有关。

确实如此。

Node* n = ...;
std::cout << n;

调用仅打印指针的重载。你需要使用:

Node* n = ...;
std::cout << *n;

如果你愿意

std::cout << n;

工作类似于

std::cout << *n;

你必须提供一个重载。

inline ostream& operator<< (ostream& out, Node* n)
{
   return (out << *n);
}

建议的改进

operator&lt;&lt; 函数应该使用const&amp;,而不是非常量引用。

inline ostream& operator<<(ostream& out, Node const& n);

这需要将print 更改为const-member 函数。

我还建议将print 的返回类型更改为std::ostream&amp;

std::ostream& print(std::ostream& out) const;

现在,实现看起来像:

std::ostream& Node::print(std::ostream& out)
{
    return (out<< freq << "  " << input<<"  " << Left<< "  " << Right<< std::endl);
}

inline std::ostream& operator<<(std::ostream& out, Node const& n)
{
   return n.print(out);
}

inline std::ostream& operator<<(std::ostream& out, Node const* n)
{
   return (out << *n);
}

【讨论】:

  • 请注意:如果重载operator&lt;&lt;(ostream&amp; out, Node const* n),您将无法像这样打印指向Node的指针的实际值:Node* n_ptr = new Node(); std::cout &lt;&lt; n_ptr &lt;&lt; std::endl,因为它总是会调用重载的operator&lt;&lt;。在这种情况下,您必须通过类似于以下的技巧来避免重载运算符:std::cout &lt;&lt; reinterpret_cast&lt;ptrdiff_t&gt;(n_ptr) &lt;&lt; std::endl;
【解决方案2】:

为什么要使用打印功能?相反,您可以只使用带有友元函数的重载。以前在实现这一点时,我需要通过 const 引用传递对象,例如 const Node &amp;name 并且还返回一个 ostream&amp;

假设 freq 和 input 是该类的成员,您的代码在 .cpp 中应该如下所示:

ostream& operator<<(ostream& out,  const Node& n)
{
   return out<<n.freq<< "  " <<n.input<<"  "<<n.Left<<"  "<< n.Right;
}

这个在 .h:

friend ostream& operator<<(ostream& out, const Node& n);

如果这需要指针,您可以简单地将其修改为:

ostream& operator<<(ostream& out,  const Node* n)
{
   return out<<n->freq<< "  " <<n->input<<"  "<<n->Left<<"  "<< n->Right;
}

和:

friend ostream& operator<<(ostream& out, const Node* n);

我希望这会有所帮助!

【讨论】:

  • 请注意:const Node&amp; n 重载是黄金标准,但我可能会避免 const Node* n 重载,因为它会阻止您在这种情况下打印指针值本身就像这样:Node* n = new Node(); std::cout &lt;&lt; n &lt;&lt; std::endl;,对于第一次使用您的代码的人来说,这可能是一个相当大的惊喜。为此,我可能只坚持const Node&amp; n 过载。
  • 我明白了,所以你建议只保留第一个,当想要打印指针数据时,我会改用&lt;&lt;*n
  • 没错,恕我直言,这是最好的方法。
  • OP 使用print 函数的方法没有任何问题。
猜你喜欢
  • 1970-01-01
  • 2012-05-29
  • 2011-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多