Стандартная библиотека ввода-вывода описана на с. 605 стандарта (см. п. 27 в [1]). Прежде чем рассматривать возможности ввода-вывода, разберемся с иерархией основных классов библиотеки (листинг 14.1). Иерархия довольно сложная и построена с использованием шаблонов, а также виртуального и множественного наследования.
Листинг 14.1. Иерархия классов объектно-ориентированной библиотеки ввода-вывода
class ios_base { ... }; template<...>class basic_ios: public ios_base; template<... >class basic_i stream: virtual public basic__ios<... >; template<... >class basic__ostream: virtual public basic_ios<.. .>; template<...>class basic_iostream: // множественное наследование public basic_istream<...>, public basic_ostream<...>; templates..>class basic_fstream: public basic_iostream<...>; template<...>class basic_stringstream: public basic_iostream<...>; template<... >class basic__if stream: public basic_istream<. .. >; template<...>class basic_ofstream: public basic_ostream<...>; template<...>class basic_istringstream: public basic_istream<...>; template<...>class basic_ostringstream: public basic_ostream<...>; templates..>class basic_streambuf { ... }; template<...>class basic_filembuf: public basic_streambuf<...>; template<... >class basic__stringbuf: public basic_streambuf <.. . >;
Все классы включены в стандартное пространство имен std. Базовым классом является класс ios_base (см. п. п. 24.4.2 в [1]). Это — не шаблонный класс, и он не зависит от типа символов. В этом классе определены доступные пользователю константы, поля и методы, управляющие состоянием потока и форматированием.
Все остальные классы — шаблонные. Все классы-шаблоны имеют два обязательных параметра: тип символов и класс свойств (трактовок) символов. Например, определение шаблона basic_ios выглядит так:
namespace std {
template <class charT,
class traits = char_traits<chart> > class basic_ios;
Параметр charT определяет тип символов, а параметр traits — класс свойств. Кроме того, в пространстве std определены специализации шаблонов для двух типов символов (char — «узкие», wchar_t — «широкие»), например:
namespace std {
typedef basic__iostream<char> iostream; // узкий поток
typedef basic_iostream<wchar_t> wiostream; // широкий поток
}
Для совместимости с предыдущей (достандартной) реализацией библиотеки определены две специализации шаблона basic_ios:
namespace std {
typedef basic_ios<char> ios; typedef basic_ios<wchar_t> wios;
}
Благодаря подобным определениям мы избавлены от необходимости писать длинные обозначения классов ввода-вывода.
Как мы знаем, определения нового класса обычно помещаются в отдельную единицу трансляции (см. главу 13). В этом случае может иногда возникнуть необходимость в опережающих объявлениях потоковых классов. Так как потоковые классы представляют собой шаблоны, то простое объявление, наподобие следующего, работать не будет:
class ostream;
Если вы решили бросить программирование и открыть свою диспетчерскую, тогда вам необходима http://baskettaxi.ru/. Программа позволит связываться с таксистами без рации.
В объектно-ориентированной библиотеке опережающие объявления всех потоковых классов собраны в специальный системный модуль (см. п. 27.2 в [1]), который подключается оператором
#include <iosfwd>
Использование модуля <iosfwd> вместо полных определений из модуля <ios-tream> существенно сокращает время трансляции для больших многомодульных программ. |