为什么仅仅调用一个对象会做某事?

  • 本文关键字:一个对象 调用 c++
  • 更新时间 :
  • 英文 :


我刚刚从LinkedIn学习中完成了C ++基本培训,现在我有一个简单的问题。 为什么cout会输出,我们只是在调用对象,但为什么仅仅调用一个对象会做一些事情。我的猜测是"<<"重载运算符是做某事的运算符,但接下来是"<<std::endl;",使用 endl,我们再次只是调用对象,但它创建了一个新行。谁能解释为什么会这样?

std::cout 是一个ostream对象,可通过标准库获得。 当您调用时

std::cout << 42;

它查找ostream& operator<<(ostream&, int)的重载,或者在本例中查找对象的成员函数 (ostream& operator<<(int)),并将 cout 传递给此运算符(或作为this)和整数。 运算符的主体将整数值写入流并返回流对象,从而允许链接:

std::cout << 42 << std::endl;

实际上是将 42 插入 ostream 中,返回 cout,然后将endl"插入"到流中,这会找到另一个重载运算符,该运算符写入换行符然后刷新流。 std::ostream(std::cout 是其中之一)有一些内置运算符<<重载作为成员,但对于普通的用户定义类型,您通常会编写非成员运算符<<重载或成员友元重载。

这不是魔术,但它有点微妙,因为在这种情况下,中缀运算符被转换为"正常"函数调用。 因此,对于某些带有重载运算符的X类型的对象x<<对于它:

class X { /*impl stuff*/ };
std::ostream& operator<<(std::ostream&, X const&);

然后

std::cout << x << std::endl;

可以被认为是一种漂亮的方法:

(std::operator<<(std::cout, x)).operator<<(std::endl);

其中内部运算符<<首先被调用,重载x,其返回值(即cout)具有其成员函数运算符<<以std::endl作为参数调用。 对于好奇的人来说,std::endl 实际上是一个函数,我们正在传递一个函数指针到运算符<<的重载,它是 std::cout 的成员:

// member overload of operator<< which is used with std::endl
basic_ostream& operator<<(
std::basic_ostream<CharT,Traits>& (*func(
std::basic_ostream<CharT,Traits>&)
);

这是流操纵器的正常工作方式。 这似乎有点复杂,但它允许一个漂亮的<<标记序列,而无需在表达式链中写出括号或"点"。 它实际上会将一个函数插入到流中,运算符<<接收函数指针,调用该函数将流对象传递给它(即调用 std::endl(this)),然后 endl 作为普通函数运行,在流中插入换行符并在其上调用 flush(),然后返回流, 可由下一个对运算符<<的链接调用使用。 这是一个很少有人真正需要知道(或关心)的细节水平,除非你正在编写操纵器,但恕我直言,这很有趣。

最新更新