How will the circuit below garantees be only one definition for cin, cout, ... objects?

Here you will find the following instructions in which heading? :

Finally, <iostream> provides eight standard global objects (cin, cout, etc.). To do this correctly, this header also provides the contents of the <istream> and <ostream> , but nothing else. the contents of this header look like

 #include <ostream> #include <istream> namespace std { extern istream cin; extern ostream cout; .... // this is explained below static ios_base::Init __foo; // not its real name } 

Now, the previously mentioned runtime limitation: global objects must be initialized before any of your own codes uses them; This is guaranteed by the standard. Like any other global object, they must be initialized once and only once. This is usually done using the same as above, and the nested class ios_base :: Init specified in the standard is for this reason.

How it works? Since a header is included before any of your code, an __foo object is created before any of your objects. (Global objects are built in the order in which they are declared and destroyed in the reverse order.) When the designer starts for the first time, eight stream objects are created.

My question is: when I include the <iostream> header file in several .cpp files, how does the diagram above guarantee that there will be only one for cin objects, cout , etc ??

+4
source share
1 answer

In fact, this does not guarantee. One determination problem is solved by simply defining the flow objects once in the .cpp file, which is part of the library. The code in the question simply contains a declaration of standard threads.

Which is a guarantee that objects will be initialized before use. One problem with global objects in C ++ is that although they are initialized in order in each .cpp file, we do not know the order in which the linker will place objects from separate files. This can cause problems if one object tries to use another object before it is initialized, and we don’t know the exact order - see Fixing the order of static initialization .

One workaround used here is to add an Init object to the header declaring the stream objects. Since you must include the header before using the stream, we know that this Init object will be at the top of the file and, therefore, created in front of other objects that the streams can use.

Now the constructor of the Init class is responsible for initializing the stream objects. This must be done early and only once. It’s exactly the same as before each implementation, but the code hints at the use of a counter that tracks the number of Init objects created (and, apparently, considering the first specifically).

This is one way to do this using only the standard language. Some implementations have other tricks, such as # pragma or init_priority , to convince the linker to put the library code in front of the user code. In this case, it just works by magic without using the Init class.

+3
source

All Articles