C++ 重载运算符<&书信电报;以会员身份印刷
是否有一种方法可以重载您可以使其成为类的成员,也就是在C++ 重载运算符<&书信电报;以会员身份印刷,c++,operator-overloading,iostream,C++,Operator Overloading,Iostream,是否有一种方法可以重载您可以使其成为类的成员,也就是在的左侧,您偶然发现了实现此功能的规范方法。您所拥有的是正确的。您是对的,这是实现流操作符的唯一方法-在类之外 您需要将该方法声明为friend 这就是它的工作方式。它必须是非成员,因为类构成运算符的第二个参数,而不是第一个参数。如果只使用公共接口就可以完成输出,那么就完成了。如果它需要访问非公共成员,那么您必须将其声明为好友;这就是朋友的作用 class TestClass { public: friend ostream&
的左侧,您偶然发现了实现此功能的规范方法。您所拥有的是正确的。您是对的,这是实现流操作符的唯一方法-在类之外
您需要将该方法声明为friend
这就是它的工作方式。它必须是非成员,因为类构成运算符的第二个参数,而不是第一个参数。如果只使用公共接口就可以完成输出,那么就完成了。如果它需要访问非公共成员,那么您必须将其声明为好友;这就是朋友的作用
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;
};
class测试类{
公众:
friend ostream&operator我认为一种流行的方法是使用非成员、非朋友自由的操作符您必须将其设置为非成员(因为第一个参数不是您的类)
但您可以将其写入类定义中(作为朋友):
class测试类
{
公众:
//有一个好朋友。
//这将此运算符紧密绑定到类。
//但这并不是一个问题,因为在现实中,它已经被紧紧地束缚住了。
friend ostream&Operator朋友不是应该解决这个问题的朋友吗?你为什么要避开他们呢?朋友是回答问题,而不是解决问题的!朋友是你的朋友。你为什么要避开他们呢?我建议你阅读和。通常不需要将函数声明为朋友g您的输出是类的公共接口的一部分(在模板中将其声明为好友通常是合适的,以便使用Barton和Nackman技巧,但这是另一个问题)这并不是实现它的唯一方法。我见过并实现了大多数流操作符,但没有将它们绑定为friend
。只有在必要的情况下,才应该使用friend
。@phresnel我经常使用print
方法,使用类模板。不是为了获得访问权限,而是为了能够在其中定义函数类。在他的例子中,成员是私有的,因此需要友谊。这比添加getter要简单得多,只供流使用。我支持上面使用友元声明的解决方案。它维护封装并完成任务。@broc我看不到封装中有任何真正的区别。在一个例子中,类的作者为operator@JamesKanze你可能会争辩说,声明一个成员public只是作者明确地给予每个人访问权,因此它不会破坏封装。你是否购买它取决于你的底线。我个人认为底线必须尽可能远尽可能以相反的方向;使用print方法可以在.dll中分发类,在没有源代码的情况下分发它,并且仍然允许库的用户编写重载的类operator@JamesKanze对于这种语言,我不能不同意你的看法,但是,这种语言是用来创建一个可执行文件或一个库的出于专业开发的目的,封装的概念必须比仅仅从语言的角度思考更深入。@broc声明成员public会放松封装,因为它使成员成为公共接口的一部分。声明函数friend
会使该函数成为类的public int的一部分通过使函数成为接口的一部分,而不是数据,实际上增加了封装。函数太多(或设计糟糕的函数,如getter和setter)也削弱了封装,但在这方面,函数是友元还是成员是无关紧要的。我没有。我只是说,如果希望它成为类成员,那么类应该是std::ostream
。这基本上意味着不,您不希望它成为类成员。谢谢,这个解决方案也适用于其他ove的输出rload运算符。对于例如cout有关此主题的更详尽的答案,请参阅本文中的接受答案不正确,因为它不会编译。在问题的设置中,必须编写一些丑陋的内容,如obj
ostream& operator<<(ostream& os, TestClass& obj) {
return os << "I'm outside of the class and can't access msg" << endl;
}
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;
};
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;
}
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;
};