C++相当于Java的toString?

Bog*_*lan 145 c++

我想控制写入流的内容,即cout自定义类的对象.这可能在C++中?在Java中,您可以toString()为了类似的目的覆盖该方法.

sth*_*sth 167

在C++中,你可以重载operator<<ostream你的自定义类:

class A {
public:
  int i;
};

std::ostream& operator<<(std::ostream &strm, const A &a) {
  return strm << "A(" << a.i << ")";
}
Run Code Online (Sandbox Code Playgroud)

这样您就可以在流上输出类的实例:

A x = ...;
std::cout << x << std::endl;
Run Code Online (Sandbox Code Playgroud)

如果您operator<<想要打印出类的内部A并且确实需要访问其私有和受保护的成员,您还可以将其声明为友元函数:

class A {
private:
  friend std::ostream& operator<<(std::ostream&, const A&);
  int j;
};

std::ostream& operator<<(std::ostream &strm, const A &a) {
  return strm << "A(" << a.j << ")";
}
Run Code Online (Sandbox Code Playgroud)

  • 最好将运算符<<声明为类的友元函数,因为可能需要访问类的私有成员. (15认同)
  • 更好的是将它声明为`friend`,并且也在类的主体内部 - 使用它,你不必为包含运算符(和类)的命名空间使用`namespace`,但是ADL会找到它只要该类的对象是操作数之一. (4认同)
  • @fnieto:`dump`公共方法很脏而且没必要.在这里使用"朋友"非常好.你喜欢冗余的方法还是侵入性的"朋友"完全是一种品味问题,尽管"朋友"可以说是出于这个目的而被引入. (2认同)

fni*_*eto 50

你也可以这样做,允许多态:

class Base {
public:
   virtual std::ostream& dump(std::ostream& o) const {
      return o << "Base: " << b << "; ";
   }
private:
  int b;
};

class Derived : public Base {
public:
   virtual std::ostream& dump(std::ostream& o) const {
      return o << "Derived: " << d << "; ";
   }
private:
   int d;
}

std::ostream& operator<<(std::ostream& o, const Base& b) { return b.dump(o); }
Run Code Online (Sandbox Code Playgroud)

  • 虚函数+1,用于复制Java的“ toString”行为。 (3认同)

小智 28

在C++ 11中,to_string最终被添加到标准中.

http://en.cppreference.com/w/cpp/string/basic_string/to_string

  • 这是对此页面的有用补充,但C++实现与Java/C#中的实现明显不同.在这些语言中,`ToString()`是在*all*对象的基类上定义的虚函数,因此用作表示任何对象的字符串表示的标准方法.`std :: string`上的这些函数仅适用于内置类型.C++中的惯用方法是覆盖自定义类型的`<<`运算符. (15认同)
  • `operator <<的标准签名的"丑陋",与Java的简单`String`语义相比,提示我注意,`to_string()`不仅是"一个有用的补充",而是新的首选方式用C++做.如果,如OP所示,需要一个类"A"的自定义字符串表示,只需在`class A'的定义下面写一个`字符串to_string(A a)`即可.这与Java中的继承一样传播,并且可以像在Java中那样组合(通过字符串添加).无论如何,Java中的非重写`toString()`的用途有限. (9认同)

blw*_*y10 10

作为John所说的扩展,如果你想提取字符串表示并将其存储在std::string这样做:

#include <sstream>    
// ...
// Suppose a class A
A a;
std::stringstream sstream;
sstream << a;
std::string s = sstream.str(); // or you could use sstream >> s but that would skip out whitespace
Run Code Online (Sandbox Code Playgroud)

std::stringstream位于<sstream>标题中.

  • 这是获得序列化字符串的一种荒谬的麻烦方式! (2认同)

小智 7

问题已得到解答.但我想补充一个具体的例子.

class Point{

public:
      Point(int theX, int theY) :x(theX), y(theY)
      {}
      // Print the object
      friend ostream& operator <<(ostream& outputStream, const Point& p);
private:
      int x;
      int y;
};

ostream& operator <<(ostream& outputStream, const Point& p){
       int posX = p.x;
       int posY = p.y;

       outputStream << "x="<<posX<<","<<"y="<<posY;
      return outputStream;
}
Run Code Online (Sandbox Code Playgroud)

此示例需要了解操作员过载.