X-Git-Url: https://oss.titaniummirror.com/gitweb/?a=blobdiff_plain;f=libstdc%2B%2B-v3%2Fdoc%2Fhtml%2Fmanual%2Fiostream_objects.html;fp=libstdc%2B%2B-v3%2Fdoc%2Fhtml%2Fmanual%2Fiostream_objects.html;h=5b6de7060c63787c73bc746bd45c851862c9aebe;hb=6fed43773c9b0ce596dca5686f37ac3fc0fa11c0;hp=0000000000000000000000000000000000000000;hpb=27b11d56b743098deb193d510b337ba22dc52e5c;p=msp430-gcc.git diff --git a/libstdc++-v3/doc/html/manual/iostream_objects.html b/libstdc++-v3/doc/html/manual/iostream_objects.html new file mode 100644 index 00000000..5b6de706 --- /dev/null +++ b/libstdc++-v3/doc/html/manual/iostream_objects.html @@ -0,0 +1,119 @@ + + +Chapter 24. Iostream Objects

Chapter 24. Iostream Objects

To minimize the time you have to wait on the compiler, it's good to + only include the headers you really need. Many people simply include + <iostream> when they don't need to -- and that can penalize + your runtime as well. Here are some tips on which header to use + for which situations, starting with the simplest. +

<iosfwd> should be included whenever you simply + need the name of an I/O-related class, such as + "ofstream" or "basic_streambuf". Like the name + implies, these are forward declarations. (A word to all you fellow + old school programmers: trying to forward declare classes like + "class istream;" won't work. Look in the iosfwd header if + you'd like to know why.) For example, +

+    #include <iosfwd>
+
+    class MyClass
+    {
+        ....
+        std::ifstream&   input_file;
+    };
+
+    extern std::ostream& operator<< (std::ostream&, MyClass&);
+   

<ios> declares the base classes for the entire + I/O stream hierarchy, std::ios_base and std::basic_ios<charT>, the + counting types std::streamoff and std::streamsize, the file + positioning type std::fpos, and the various manipulators like + std::hex, std::fixed, std::noshowbase, and so forth. +

The ios_base class is what holds the format flags, the state flags, + and the functions which change them (setf(), width(), precision(), + etc). You can also store extra data and register callback functions + through ios_base, but that has been historically underused. Anything + which doesn't depend on the type of characters stored is consolidated + here. +

The template class basic_ios is the highest template class in the + hierarchy; it is the first one depending on the character type, and + holds all general state associated with that type: the pointer to the + polymorphic stream buffer, the facet information, etc. +

<streambuf> declares the template class + basic_streambuf, and two standard instantiations, streambuf and + wstreambuf. If you need to work with the vastly useful and capable + stream buffer classes, e.g., to create a new form of storage + transport, this header is the one to include. +

<istream>/<ostream> are + the headers to include when you are using the >>/<< + interface, or any of the other abstract stream formatting functions. + For example, +

+    #include <istream>
+
+    std::ostream& operator<< (std::ostream& os, MyClass& c)
+    {
+       return os << c.data1() << c.data2();
+    }
+   

The std::istream and std::ostream classes are the abstract parents of + the various concrete implementations. If you are only using the + interfaces, then you only need to use the appropriate interface header. +

<iomanip> provides "extractors and inserters + that alter information maintained by class ios_base and its derived + classes," such as std::setprecision and std::setw. If you need + to write expressions like os << setw(3); or + is >> setbase(8);, you must include <iomanip>. +

<sstream>/<fstream> + declare the six stringstream and fstream classes. As they are the + standard concrete descendants of istream and ostream, you will already + know about them. +

Finally, <iostream> provides the eight standard + global objects (cin, cout, etc). To do this correctly, this header + also provides the contents of the <istream> and <ostream> + headers, 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 runtime penalty mentioned previously: the global objects + must be initialized before any of your own code uses them; this is + guaranteed by the standard. Like any other global object, they must + be initialized once and only once. This is typically done with a + construct like the one above, and the nested class ios_base::Init is + specified in the standard for just this reason. +

How does it work? Because the header is included before any of your + code, the __foo object is constructed before any of + your objects. (Global objects are built in the order in which they + are declared, and destroyed in reverse order.) The first time the + constructor runs, the eight stream objects are set up. +

The static keyword means that each object file compiled + from a source file containing <iostream> will have its own + private copy of __foo. There is no specified order + of construction across object files (it's one of those pesky NP + problems that make life so interesting), so one copy in each object + file means that the stream objects are guaranteed to be set up before + any of your code which uses them could run, thereby meeting the + requirements of the standard. +

The penalty, of course, is that after the first copy of + __foo is constructed, all the others are just wasted + processor time. The time spent is merely for an increment-and-test + inside a function call, but over several dozen or hundreds of object + files, that time can add up. (It's not in a tight loop, either.) +

The lesson? Only include <iostream> when you need to use one of + the standard objects in that source file; you'll pay less startup + time. Only include the header files you need to in general; your + compile times will go down when there's less parsing work to do. +