我想控制写入流的内容,比如一个自定义类对象的cout
。在C++中是否可能实现?在Java中,你可以通过重写toString()
方法来实现类似的功能。
我想控制写入流的内容,比如一个自定义类对象的cout
。在C++中是否可能实现?在Java中,你可以通过重写toString()
方法来实现类似的功能。
在 C++ 中,您可以为 ostream
和自定义类重载 operator<<
:
class A {
public:
int i;
};
std::ostream& operator<<(std::ostream &strm, const A &a) {
return strm << "A(" << a.i << ")";
}
这种方式可以在流中输出类的实例:
A x = ...;
std::cout << x << std::endl;
如果你的 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 << ")";
}
你还可以使用这种方法,实现多态:
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); }
toString
的行为,建议使用虚函数,并给其加上 +1。 - Konrad RudolphC++11标准中,终于添加了to_string函数。
http://en.cppreference.com/w/cpp/string/basic_string/to_string
String
语义相比,operator<<
标准签名的“丑陋”促使我评论说,to_string()
不仅是“有用的补充”,而且是在C++中进行此操作的新首选方法。如果需要类A
的自定义字符串表示,则在class A
的定义下方编写string to_string(A a)
就足够了。这将像Java一样传播到继承中,并且可以通过字符串添加(如Java)组合。在Java中,未重写的toString()
本来就有限制使用。 - P Mareckiclass 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;
}
这个例子需要理解运算符重载。
扩展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
std::stringstream
位于<sstream>
头文件中。
friend
,并在类的内部进行声明 - 这样一来,您就不必为包含运算符(和类)的命名空间使用using namespace
,但只要该类的对象是操作数之一,ADL 就会找到它。 - Pavel Minaevdump
公共方法很不好,也没必要。在这里使用friend
是完全可以的。你喜欢多余的方法还是侵入式的friend
完全是个人口味问题,尽管可以说friend
就是为了这个目的而引入的。 - Konrad Rudolphoperator<<()
作为成员函数无法起作用:您必须将其作为std::ostream
的成员函数,以使其接受类型为std :: ostream
的左操作数。 - sth