c++ - 为什么仅仅调用一个对象会有所作为?

标签 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 是其中之一)有一些内置的 operator<< 重载作为成员,但是对于普通的用户定义类型,您通常编写非成员 operator<< 重载,或者成员 < em>friend 重载。

这并不神奇,但有点微妙,因为在这种情况下,中缀运算符被翻译成“正常”函数调用。因此对于某些对象 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)的成员函数 operator<< 以 std::endl 作为参数调用。出于好奇,std::endl 实际上是一个函数,我们将一个函数指针 传递给 operator<< 的重载,它是 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>&)
);

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

关于c++ - 为什么仅仅调用一个对象会有所作为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67084688/

相关文章:

c++ - void* 和 void** 有什么区别?

c++ - 按不同字段对结构队列进行排序

c++ - c++中没有timeout_exception吗?

c++ - 在以下情况下我是否需要使用 wstring

c++ - 按键值搜索无序二叉树

C++ - shared_ptr<vector<T>> 与 vector<shared_ptr<T>>

C++ 在接收整数时读取 cin>> 中的空间

c++ - 我如何检查指针是否在 C++ 中被删除

c++ - 正弦和余弦哪个更有效? Sin 和 Cos 还是 Sin 和 Sqrt?

c++ - 从字符串中获取土耳其字符