有没有办法重载<< operator,作为类成员,将值打印为文本流。如:
class TestClass {
public:
ostream& operator<<(ostream& os) {
return os << "I'm in the class, msg=" << msg << endl;
}
private:
string msg;
};
int main(int argc, char** argv) {
TestClass obj = TestClass();
cout << obj;
return 0;
}
我能想到的唯一方法是在课堂外重载操作员:
ostream& operator<<(ostream& os, TestClass& obj) {
return os << "I'm outside of the class and can't access msg" << endl;
}
但是,访问对象私有部分的唯一方法是与操作员函数联系,如果可能的话我宁愿避开朋友,因此请求您提供替代解决方案。
有关如何进行的任何意见或建议都会有所帮助:)
答案 0 :(得分:8)
它必须是非成员,因为类形成运算符的第二个参数,而不是第一个参数。如果输出只能使用公共接口完成,那么就完成了。如果它需要访问非公开成员,那么你必须声明它是朋友;这就是朋友们的目的。
class TestClass {
public:
friend ostream& operator<<(ostream& os, TestClass const & tc) {
return os << "I'm a friend of the class, msg=" << tc.msg << endl;
}
private:
string msg;
};
答案 1 :(得分:6)
我认为一种流行的方法是在会员中调用公共非虚拟operator<<
方法的非会员,非朋友免费print
。此打印方法可以执行工作或委托给受保护的虚拟实现。
class TestClass {
public:
ostream& print(ostream& os) const {
return os << "I'm in the class, msg=" << msg << endl;
}
private:
string msg;
};
ostream& operator<<(ostream& os, TestClass& obj) {
return obj.print(os);
}
int main(int argc, char** argv) {
TestClass obj;
cout << obj;
return 0;
}
答案 2 :(得分:5)
您偶然发现了实现此功能的规范方法。你有什么是正确的。
答案 3 :(得分:1)
您可以将其设为班级的成员,位于<<
的左侧,在您的情况下为ostream
。
但是,你可以做的是,有一个基类,void do_stream(ostream& o);
成员用于你所有的流量和非成员operator<<
,可以调用它。
答案 4 :(得分:0)
你是对的,这是实现流操作符的唯一方法 - 在课外。
您需要将方法声明为friend
。
这就是它的完成方式。
答案 5 :(得分:0)
你必须使它成为非成员(因为第一个参数不是你的类)。
但你可以把它写在你的班级定义中(作为朋友):
class TestClass
{
public:
// Have a nice friend.
// This tightly binds this operator to the class.
// But that is not a problem as in reality it is already tightly bound.
friend ostream& operator<<(ostream& os, TestClass const& data)
{
return os << "I'm in the class, msg=" << data.msg << endl;
}
private:
string msg;
};
我觉得把这个变成朋友是没有错的。