C++: библиотека программиста



Download 1,95 Mb.
Pdf ko'rish
bet31/144
Sana24.02.2022
Hajmi1,95 Mb.
#223123
TuriРеферат
1   ...   27   28   29   30   31   32   33   34   ...   144
Bog'liq
C -Eldjer-Djeff-for-Real-Programmers-RUS-www.itlibitum.ru

 
39 
4. Глобальные объекты, находящиеся в одном «модуле трансляции» (обычно файле с 
расширением .срр), инициализируются в порядке их появления в этом модуле. В сочетании с 
правилом 3 это означает, что инициализация может выполняться по модулям, при первом 
использовании каждого модуля. 
Вот и все. Внешне простая последовательность глобальных объявлений на самом деле полностью 
подчиняется всем капризам разработчика компилятора. Она может привести к нужному результату или 
сгореть синим пламенем. 
// В файле file1.cpp 
Foo foo; 
Foo* f = &foo; 
// В файле file2.cpp 
extern Foo* f; 
Foo f1(*f); 
// Используется конструктор копий 
Если бы все это находилось в одном исходном файле, ситуация была бы нормальной. Со строкой 
Fоо* 
f = &foo;
проблем не возникает, поскольку глобальные объекты одного исходного файла заведомо 
(хе-хе) инициализируются в порядке их определения. Другими словами, когда программа доберется до 
этой строки, объект 
foo
уже будет сконструирован. Тем не менее, никто не гарантирует, что 
глобальные объекты в файле file1.cpp будут инициализированы раньше глобальных объектов в файле 
file2.срр. Если file2.cpp будет обрабатываться первым, 
f
оказывается равным 0 (
NULL
на большинстве 
компьютеров), и при попытке получить по нему объект ваша программа героически умрет. 
Лучший выход — сделать так, чтобы программа не рассчитывала на конкретный порядок 
инициализации файлов .срр. Для этого используется стандартный прием — в заголовочном файле .h 
определяется глобальный объект со статической переменной, содержащей количество 
инициализированных файлов .срр. При переходе от 0 к 1 вызывается функция, которая инициализирует 
все глобальные объекты библиотечного файла .срр. При переходе от 1 к 0 все объекты этого файла 
уничтожаются. 
// В файле Library.h 
class Library { 
private: 
static 
int 
count; 
static void OpenLibrary(); 
static void CloseLibrary(); 
public: 
Library(); 
~Library(); 
}; 
static Library LibraryDummy; 
inline Library::Library() 

if (count++ == 0) 
OpenLibrary(); 

inline Library::~Library() 

if (--count == 0) 
CloseLibrary(); 

// В Library.cpp 
int Library::count = 0; // 
Делается перед выполнением вычислений 
int aGlobal; 


 40 
Foo* aGlobalFoo; 
void Library::OpenLibrary() 

aGlobal = 17; 
aGlobalFoo = new Foo; 

void Library::CloseLibrary() 

aGlobal = 0; 
delete 
aGlobalFoo; 
aGlobalFoo 

NULL; 

К этому нужно привыкнуть. А происходит следующее: файл .h компилируется со множеством других 
файлов .срр, один из которых - Library.cpp. Порядок инициализации глобальных объектов
встречающихся в этих файлах, предсказать невозможно. Тем не менее, каждый из них будет иметь 
свою статическую копию 
LibraryDummy
. При каждой инициализации файла .срр, в который включен 
файл Library.h, конструктор 
LibraryDummy
увеличивает счетчик. При выходе из 
main()
или при 
вызове 
exit()
файлы .срр уничтожают глобальные объекты и уменьшают счетчик в деструкторе 
LibraryDummy
. Конструктор и деструктор гарантируют, что 
OpenLibrary()
и 
CloseLibrary()
будут вызваны ровно один раз. 
Этот прием приписывается многим разным программистам, но самый известный пример его 
использования встречается в библиотеке iostream. Там он инициализирует большие структуры данных, 
с которыми работает библиотека, ровно один раз и лишь тогда, когда это требуется. 
Деструкторы 
Деструкторы вызываются каждый раз, когда стековый объект выходит из области действия (включая 
анонимные экземпляры и временные объекты, создаваемые компилятором) или когда для 
динамического объекта вызывается оператор 
delete
. К деструкторам относится ряд малоизвестных 
фактов. 
Порядок вызова 
Деструкторы гарантированно вызываются в порядке, обратном порядку вызова конструкторов. Это 
означает, что сначала вызывается тело конструктора объекта, затем деструкторы переменных класса в 
порядке, обратном порядку их перечисления в объявлении класса, и наконец деструкторы базовых 
классов, начиная с последнего в списке наследования и кончая первым базовым первого базового и т.д. 
Уничтожение глобальных объектов 
Если от разговоров об инициализации глобальных объектов у вас закружилась голова, могу вас 
обрадовать. Если разработчик вашего компилятора справился со своей работой, деструкторы 
глобальных объектов гарантированно вызываются в порядке, точно обратном порядку вызова 
конструкторов. 
Глобальные объекты уничтожаются при выходе из области действия 
main()
или при вызове 
exit()

Невиртуальные деструкторы 
C++ выбирает вызываемый деструктор по типу указателя на объект. Если указатель имеет тип 
base*
(указатель на базовый класс), возникнут проблемы, если только деструктор класса не виртуален. 
class Foo { 
public: 
~Foo(); 
}; 



Download 1,95 Mb.

Do'stlaringiz bilan baham:
1   ...   27   28   29   30   31   32   33   34   ...   144




Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©hozir.org 2024
ma'muriyatiga murojaat qiling

kiriting | ro'yxatdan o'tish
    Bosh sahifa
юртда тантана
Боғда битган
Бугун юртда
Эшитганлар жилманглар
Эшитмадим деманглар
битган бодомлар
Yangiariq tumani
qitish marakazi
Raqamli texnologiyalar
ilishida muhokamadan
tasdiqqa tavsiya
tavsiya etilgan
iqtisodiyot kafedrasi
steiermarkischen landesregierung
asarlaringizni yuboring
o'zingizning asarlaringizni
Iltimos faqat
faqat o'zingizning
steierm rkischen
landesregierung fachabteilung
rkischen landesregierung
hamshira loyihasi
loyihasi mavsum
faolyatining oqibatlari
asosiy adabiyotlar
fakulteti ahborot
ahborot havfsizligi
havfsizligi kafedrasi
fanidan bo’yicha
fakulteti iqtisodiyot
boshqaruv fakulteti
chiqarishda boshqaruv
ishlab chiqarishda
iqtisodiyot fakultet
multiservis tarmoqlari
fanidan asosiy
Uzbek fanidan
mavzulari potok
asosidagi multiservis
'aliyyil a'ziym
billahil 'aliyyil
illaa billahil
quvvata illaa
falah' deganida
Kompyuter savodxonligi
bo’yicha mustaqil
'alal falah'
Hayya 'alal
'alas soloh
Hayya 'alas
mavsum boyicha


yuklab olish