Бьерн Страуструп. Язык программирования С++ Второе дополненное издание



Pdf көрінісі
бет198/256
Дата11.07.2022
өлшемі2,87 Mb.
#37591
1   ...   194   195   196   197   198   199   200   201   ...   256
10.5.1 Закрытие потоков 
Файл может быть закрыт явно, если вызвать close() для его потока:
mystream.close(); 
Но это неявно делает деструктор потока, так что явный вызов close() может понадобиться, если только 
файл нужно закрыть до достижения конца области определенности потока. 


Бьерн Страуструп.
Язык программирования С++ 
 
277 
Здесь возникает вопрос, как реализация может обеспечить создание предопределенных потоков cout, 
cin и cerr до их первого использования и закрытие их только после последнего использования. Конечно, 
разные реализации библиотеки потоков из  могут по-разному решать эту задачу. В конце 
концов, решение – это прерогатива реализации, и оно должно быть скрыто от пользователя. Здесь 
приводится только один способ, примененный только в одной реализации, но он достаточно общий
чтобы гарантировать правильный порядок создания и уничтожения глобальных объектов различных 
типов. 
Основная идея в том, чтобы определить вспомогательный класс, который по сути служит счетчиком, 
следящим за тем, сколько раз  был включен в раздельно компилировавшиеся программные 
файлы: 
class Io_init { 
static int count; 
//... 
public: 
Io_init(); 
^Io_init(); 
}; 
static Io_init io_init ; 
Для каждого программного файла определен свой объект с именем io_init. Конструктор для объектов 
io_init использует Io_init::count как первый признак того, что действительная инициализация глобальных 
объектов потоковой библиотеки ввода-вывода сделана в точности один раз: 
Io_init::Io_init() 

if (count++ == 0) { 
// инициализировать cout 
// инициализировать cerr 
// инициализировать cin 
// и т.д. 


Обратно, деструктор для объектов io_init использует Io_count, как последнее указание на то, что все 
потоки закрыты: 
Io_init::^Io_init() 

if (--count == 0) { 
// очистить cout (сброс, и т.д.) 
// очистить cerr (сброс, и т.д.) 
// очистить cin 
// и т.д. 


Это общий прием работы с библиотеками, требующими инициализации и удаления глобальных 
объектов. Впервые в С++ его применил Д. Шварц. В системах, где при выполнении все программы 
размещаются в основной памяти, для этого приема нет помех. Если это не так, то накладные расходы, 
связанные с вызовом в память каждого программного файла для выполнения функций инициализации, 
будут заметны. Как всегда, лучше, по возможности, избегать глобальных объектов. Для классов, в 
которых каждая операция значительна по объему выполняемой работы, чтобы гарантировать 
инициализацию, было бы разумно проверять такие первые признаки (наподобие Io_init::count) при 
каждой операции. Однако, для потоков такой подход был бы излишне расточительным. 


Достарыңызбен бөлісу:
1   ...   194   195   196   197   198   199   200   201   ...   256




©emirsaba.org 2024
әкімшілігінің қараңыз

    Басты бет