Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ std::cout声明是如何工作的?_C++_Cout - Fatal编程技术网

C++ std::cout声明是如何工作的?

C++ std::cout声明是如何工作的?,c++,cout,C++,Cout,std::cout对象在iostream头文件中声明为 namespace std _GLIBCXX_VISIBILITY(default) { ... extern ostream cout; ... } 从现在起,我将删除std::前缀 因此,据我所知,cout只是一个类型为ostream的对象。我开始想知道为什么东西是用cout打印到屏幕上的,而不是用其他ostream对象,所以我尝试创建一个ostream类型的对象,但编译器不让我这样做。事实上,ostream只是basic\u ost

std::cout
对象在
iostream
头文件中声明为

namespace std _GLIBCXX_VISIBILITY(default)
{
...
extern ostream cout;
...
}
从现在起,我将删除
std::
前缀

因此,据我所知,
cout
只是一个类型为
ostream
的对象。我开始想知道为什么东西是用
cout
打印到屏幕上的,而不是用其他
ostream
对象,所以我尝试创建一个
ostream
类型的对象,但编译器不让我这样做。事实上,
ostream
只是
basic\u ostream
的别名,该类型的默认构造函数受到保护。很好,我想。但接着我想知道:为什么一开始就声明
cout
是合法的?为什么这不会导致编译器错误

我再次尝试使用关键字
extern
声明一个
ostream
,例如

extern ostream os;
os << "Will you compile?\n";
extern-ostream操作系统;
操作系统
我开始想知道为什么东西是用cout而不是其他ostream对象打印到屏幕上的

因为
std::cout
使用与
stdout
设备关联的流缓冲区

所以我尝试创建一个类型为ostream的对象,但编译器不允许。事实上,ostream只是basic_ostream的别名,该类型的默认构造函数受到保护。很好,我想。但后来我想知道:为什么cout的声明一开始就合法?为什么这不会导致编译器错误

因为它是一个声明,而不是一个定义,所以它不调用任何构造函数。也许你应该读一下
extern
在声明中的含义

带有
extern
的声明只表示程序中其他地方定义了一个对象,该对象的类型为
ostream
,名为
cout
。由于您实际上没有提供任何此类定义,因此会出现链接器错误

要大致模拟
std::cout
,可以在一些
.cpp
文件中执行此操作:

namespace {
  std::ofstream fake_cout("/dev/stdout");
}
std::ostream cout(fake_cout.rdbuf());
这将创建一个写入
/dev/stdout
fstream
,然后将名为
cout
ostream
与其流缓冲区相关联

这不是对real
std::cout
的很好的模拟,因为它不能确保流在任何其他全局成员尝试使用它之前被初始化,而real确实是这样做的

在其他地方有cout的“定义”吗?如果是,在哪里


<>是,在标准C++库的LIbSTDC++中实现了<代码> CUT/COD>的定义。这个定义不是用标准C++中有效的方式来完成的。没关系,因为标准C++库的实现不必用标准C++编写,它只需要以其他实现方式来编写。你到底在哪里定义了操作系统ῥεῖ 没有,因此问题中提到了链接器错误。
extern
关键字意味着问题中的变量是在别处定义的,编译器在链接之前不需要担心在哪里。所以,要回答“在别的地方有没有对cout的定义?”是的,肯定有。是的,我只是在黑暗中徘徊。但是我猜,
cout
是在其他地方定义的……虽然在哪里?@bartgol它提供了
lstdc++
,它是自动链接的。谢谢!我确实想知道定义在哪里,因为它不在C++包含文件夹中,所有标准头都在这里。但它是有意义的:它在标准头中声明,在源代码(即libstdc++库)中定义,在源代码中使用操作系统的缓冲区创建。现在清楚了。我忽略了一个事实,即std库不仅具有标题,而且还具有…一个库!=)谢谢你的例子!出于某种原因,我不认为cout的定义在某些源代码(或库)中,而不是在标题中。我当然找不到了!您的示例非常有用,因为它还让我在/dev文件夹中发现了stdout/err/in(我还需要学习很多关于unix系统和根目录树的知识)。谢谢另外,为什么
std::cout
保证在任何其他全局函数尝试使用它之前初始化流,而我的个人实现不会?因为不同对象中全局函数的初始化顺序未指定,请参阅标准库采取特殊预防措施以确保
std::cin
std::cout
std::cerr
在尝试使用它们的对象(通常使用。