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



Download 1,95 Mb.
Pdf ko'rish
bet120/144
Sana24.02.2022
Hajmi1,95 Mb.
#223123
TuriРеферат
1   ...   116   117   118   119   120   121   122   123   ...   144
Bog'liq
C -Eldjer-Djeff-for-Real-Programmers-RUS-www.itlibitum.ru

 
215 
которая ссылается на объект класса. К сожалению, оно связано с заметными затратами как по памяти, 
так и кода конструктора. Однако существуют два других варианта: 
1. Хранить указатель на объект класса в ведущем указателе. Получаем те же затраты, но с 
улучшенной инкапсуляцией. 
2. Выделить все экземпляры некоторого класса в одно пространство памяти и хранить указатель 
на объект класса в начале пространства (см. рисунок). 
Класс 
Объект 
Пространство 
памяти 
Второй вариант существенно снижает затраты при условии, что по адресу объекта можно эффективно 
определить начало адресного пространства памяти, которому он принадлежит (возможно, с помощью 
упомянутой выше коллекции пространств памяти). 
На первый взгляд кажется, что устраивать такую суету вокруг простейшей проблемы глупо. Почему бы 
просто не добавить дополнительную переменную, ссылающуюся на объект класса? Приведу по 
крайней мере две причины: 
1. Класс, с которым вы работаете, может входить в коммерческую библиотеку, для которой у вас 
нет исходных текстов, или его модификация нежелательна по другим причинам. 
2. Класс может представлять собой тривиальную объектно-ориентированную оболочку для 
примитивного типа данных (скажем, 
int
). Лишние байты для указателя на объект класса (не 
говоря уже о v-таблице, которая неизбежно потребуется для виртуальных функций доступа к 
нему) могут оказаться весьма существенными. 
Деление по размеру 
Вполне разумно объединить все объекты одинакового размера (или принадлежащие одному диапазону 
размеров) в одно пространство памяти для оптимизации создания и уничтожения. Многие стратегии 
управления памятью работают для одних диапазонов лучше, чем для других. Например, при создании 
множества больших, сильно различающихся по размерам объектов схема со степенями 2 наверняка 
оставит много неиспользованных фрагментированных блоков. Однако для объектов относительно 
малых (или близких по размеру к степеням 2) такая схема работает просто замечательно. В крайних 
случаях все пространство памяти может заполняться объектами одинакового размера. Такие 
пространства обладают чрезвычайно эффективным представлением и легко управляются. 
Деление по способу использования 
Еще один возможный вариант — делить объекты в соответствии со способом их использования. 
Например, для многопоточного приложения-сервера объекты можно разделить по клиентам. Редко 
используемые объекты могут находиться в одном пространстве, а часто используемые — в другом. 
Объекты, кэшируемые на диске, могут отделяться от объектов, постоянно находящихся в памяти. 
Деление может осуществляться как на уровне классов, так и на уровне отдельных объектов. 
Деление по средствам доступа 
Другая важная причина для разделения по пространствам памяти заключается в том, чтобы хранить по 
отдельности объекты, доступ к которым осуществляется из стека, из других процессов или чисто 


 216 
внутренние из кучи. Как будет показано в последних главах, это играет важную роль в схемах 
уплотнения и сборки мусора. 
В двух следующих главах эта методика будет применяться довольно часто. Перемещаемые объекты 
отделяются от объектов, остающихся на одном месте. Ведущие указатели, доступные из стека, 
находятся в одном пространстве памяти, а доступные из других процессов — в другом. 
Пространства стека и кучи 
Наконец, сам стек тоже можно считать разновидностью пространства памяти, а выделяемые в стеке 
пулы — их частным случаем. Этот подход применялся ранее в этой главе для пулов, локальных по 
отношению к области действия конкретной функции. Эта особая интерпретация стека упоминается и в 
двух последующих главах. 


Уплотнение 
памяти 
Представьте себе обычное управление памятью в С++: вы зажигаете благовония, приносите жертву 
божествам операционной системы и удаляете объект. Если все идет нормально, объект будет должным 
образом деинициализирован и уничтожен и никто никогда не попытается им воспользоваться. Ха! 
Всем известно, что в реальной жизни так не бывает. 
Одна из главных достопримечательностей динамических языков — таких как SmallTalk и Lisp — не 
имеет никакого отношения к самому языку, а лишь к тому, что он удаляет объекты за вас
автоматически и надежно. Выходит потрясающая экономия времени и энергии, не говоря уже о 
благовониях и жертвах. Можно ли то же самое сделать на С++? Вместо прямолинейного «да» или 
«нет» я отвечу: «Все зависит от того, сколько труда вы хотите вложить в решение». 
В этой главе начинается настоящее веселье — вы увидите, как перемещать объекты в памяти, чтобы 
свести к минимуму фрагментацию свободной памяти. Надеюсь, при виде моих алгоритмов никто не 
будет кататься по полу от смеха. Заодно мы подготовим сцену для полноценных алгоритмов сборки 
мусора, о которых речь пойдет в следующей главе. 
Поиск указателей 
Помимо подсчета ссылок и нестандартных операторов 
new
и 
delete
в большинстве стратегий 
управления памятью сочетаются две методики: определение момента, когда доступ к объекту 
становится невозможным, для его автоматического уничтожения (сборка мусора) и перемещение 
объектов в памяти (уплотнение). В свою очередь, эти стратегии зависят от того, что в других языках 
делается легко и просто, но оказывается дьявольски сложным в С++ — от задачи поиска всех 
указателей на объекты. 
Поиск указателей в программе на С++ чрезвычайно сложен, поскольку компилятор не оставляет 
никаких инструкций на этот счет. Более того, в С++ программа может получить адрес части объекта, 
поэтому некоторые указатели могут ссылаться на середину большого объекта. 
Мама, откуда берутся указатели? 
В С++ существуют невероятно разнообразные способы получения указателей. Одни связаны с 
конкретным представлением объектов в памяти, другие — с наследованием, третьи — с переменными 
классов. Конечно, самый очевидный способ — это нахождение адреса. А теперь давайте рассмотрим 
другие, не столь тривиальные способы. 
Адреса переменных класса 
Имея объект, вы можете получить адрес переменной класса, поспользоваться им или передать другому 
объекту. 
class Foo { 
private: 
int 
x; 
String 
y; 

Download 1,95 Mb.

Do'stlaringiz bilan baham:
1   ...   116   117   118   119   120   121   122   123   ...   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