std::cout
对象在iostream
头文件中声明为
namespace std _GLIBCXX_VISIBILITY(default)
{
...
extern ostream cout;
...
}
从现在开始,我将删除
std::
前缀。因此,据我所知,
cout
是“只是” ostream
类型的对象。我开始想知道为什么将东西用cout
而不是其他ostream
对象打印到屏幕上,所以我尝试创建ostream
类型的对象,但是编译器不允许我这样做。实际上,ostream
只是basic_ostream<char>
的别名,该类型的默认构造函数受到保护。很好,我想。但是后来我想知道:为什么cout
的声明以合法开头?为什么不发出编译器错误?我再次尝试使用关键字
ostream
声明extern
,例如extern ostream os;
os << "Will you compile?\n";
这次我得到了对os的未定义引用错误。然后问题就转移到以下地方:在其他地方是否存在
cout
的“定义”?如果是这样,在哪里?我无法解决这个问题。我知道,出于性能和安全性的考虑,标准 header 以一种“神秘”的方式编写,除非您完全完全掌握了该语言(我仍然不太可能),否则它并不总是易于阅读,但是我d想了解这一点。
谢谢。
最佳答案
因为std::cout
使用与stdout
设备关联的流缓冲区。
因为它是声明,而不是定义,所以它不会调用任何构造函数。也许您应该阅读extern
在声明中的含义。
带有extern
的声明仅表示在程序的其他位置定义了一个对象,该对象的类型为ostream
,称为cout
。由于您实际上未提供任何此类定义,因此会出现链接器错误。
要大致模拟std::cout
,可以在一些.cpp
文件中执行以下操作:
namespace {
std::ofstream fake_cout("/dev/stdout");
}
std::ostream cout(fake_cout.rdbuf());
这将创建一个
fstream
并写入/dev/stdout
,然后将名为ostream
的cout
与它的流缓冲区相关联。这不是真实的
std::cout
的良好模拟,因为它不能确保在任何其他全局变量尝试使用它之前就初始化该流,真实的人会这样做。