这些行只是将处理 Telegram 对象的功能添加到标准输出流类中。
当您添加一个新类并且您想要输出流时,例如cout
要智能地处理它们,您需要添加一个新的<<
将新对象类型作为第二个参数的运算符方法。
上面的代码所做的就是这个。当您稍后执行语句时:
Telegram tg("Bob", "Hello, how are you?");
cout << tg;
你的问题中的函数将被调用,流作为第一个参数,你的tg
object 作为第二个参数,然后它将能够以适合该类的格式输出数据。
这实际上是我难以理解的早期 C++ 事物之一。尽管该类应该是独立的,但您实际上是在向不同的处理输出的类。一旦你明白为什么会发生这种情况(因为这是ostream
负责输出内容的类而不是你自己的类),它希望是有意义的。
希望用一个更简单的例子让它更清楚:
1 inline std::ostream& operator<<(std::ostream& os, const Telegram& t) {
2 os << "message: " << t.Msg;
3 return os;
4 }
第 1 行只是函数定义。它允许您返回流本身(您传入的),以便您可以链接<<
段。这operator<<
只是您提供的函数,即您输入时调用的函数<< tg
到输出流语句中。
第2行使用更基本的<<
已定义的语句(在本例中,无论 Msg 是什么类型,都可能是字符串)。
然后第 3 行返回流,再次允许链接<<
段。
基本思想是提供operator<<
建立在现有功能之上operator<<
构成您的类型的数据类型的函数。
并使用一个简单的包装类,其中仅包含一个int
:
#include <iostream>
// This is my simple class.
class intWrapper {
public:
intWrapper (int x) { myInt = x; };
int getInt (void) { return myInt; }
private:
int myInt;
// Must be friend to access private members.
friend std::ostream& operator<< (std::ostream&, const intWrapper&);
};
// The actual output function.
inline std::ostream& operator<< (std::ostream& os, const intWrapper& t) {
os << "int: " << t.myInt;
return os;
}
// Main program for testing.
// Output with getter and with ostream.
int main (void) {
class intWrapper x(7);
std::cout << x.getInt() << std::endl; // ostream already knows about int.
std::cout << x << std::endl; // And also intWrapper, due to the
// function declared above.
return 0;
}
这输出:
7
int: 7
第一个通过调用 getter 函数来检索整数,第二个通过调用<<
我们添加到的运算符函数ostream
.