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



Download 1,95 Mb.
Pdf ko'rish
bet134/144
Sana24.02.2022
Hajmi1,95 Mb.
#223123
TuriРеферат
1   ...   130   131   132   133   134   135   136   137   ...   144
Bog'liq
C -Eldjer-Djeff-for-Real-Programmers-RUS-www.itlibitum.ru

 
243 
логических объектов внутри него — одни являются переменными класса, а другие — базовыми 
классами. Как правило, адреса этих объектов отличны от того объекта, которому они принадлежат. 
Анализ экземпляров 
Алгоритмы сборки мусора обычно начинают свою работу с периметра. Для каждого объекта периметра 
составляется список объектов, которые он содержит и на которые ссылается. Затем для каждого такого 
объекта составляется новый список и т.д. Рекурсивный перебор продолжается до тех пор, пока удается 
находить новые объекты. Для этого нам понадобятся некоторые средства, которые позволяют для 
данного объекта найти все его внедренные объекты и указатели/ссылки. 
В SmallTalk и других динамических языках описание структуры экземпляра является задачей объекта 
класса. В С++ существует несколько вариантов. Первые два решения (см. ниже) вполне практичны, а 
третье — отчаянная мера, которая подходит только для профессиональных каскадеров на закрытых 
треках. 
Виртуальные функции 
Если все объекты происходят от одного общего базового класса, в этом базовом классе можно 
объявить виртуальную функцию для перечисления указателей и внедренных объектов. Эта функция 
переопределяется в каждом классе, который добавляет новые переменные или объединяет базовые 
классы посредством множественного наследования. 
Объекты классов 
Вы также можете создать свои собственные объекты классов, как было показано в предыдущих главах, 
и научить их перечислять внедренные объекты и указатели в экземплярах. 
Осведомленные указатели 
В крайнем случае можно воспользоваться умными указателями и обращаться к ним с просьбой описать 
объект. 
class Foo { 
private: 
Bar* 
bar; 
}; 
class PFoo { // Умный указатель на Foo 
private: 
Foo* 
foo; 
public: 
FunctionThatEnumeratesPointersInFoo(); 
}; 
Почему я называю этот случай крайним? Вы рискуете тем, что указатель неверно определит тип 
объекта, на который он ссылается. Конечно, если 
PFoo
— ведущий указатель, мы знаем, что foo 
действительно является 
Foo*
, но что делать с 
bar
? Как узнать, что это действительно 
Bar
, а не что-то 
производное от него? Если 
Bar
не имеет только что упоминавшейся самоописывающей виртуальной 
функции и не возвращает объект класса, остается одно — повсюду раскидать умные указатели и 
надеяться на лучшее. 
class Bar { 
}; 
class Pbar { // Умный указатель на Bar 
}; 
class Foo { 
private: 
Pbar 
bar; 
}; 


 244 
class PFoo { // Умный указатель на Foo 
private: 
Foo* 
foo; 
public: 
FunctionThatEnumeratesPointersInFoo(); 
}; 
Теперь мы начинаем с одного умного указателя, 
PFoo
, и рекурсивно находим другой, 
PBar
. Каждый из 
этих умных указателей разбирается в особенностях строения объекта, на который он ссылается. В этом 
они превзошли умные указатели, поэтому я называю их осведомленными (ingenious), хотя циник, 
вероятно, назвал бы их нерассуждающими
Перебор графа объектов 
В дальнейшем мы воспользуемся методикой виртуальных функций из приведенного выше списка, хотя 
материал с таким же успехом применим и к объектам классов. Перечисление реализуется двумя 
основными способами: с применением рекурсивных функций и функторов, а также с применением 
итераторов. 
Рекурсивные функции и функторы 
Первая естественная реакция: организовать механизм косвенного вызова, создать функцию или 
функтор, вызываемые для каждого доступного объекта, и подождать, пока закончится рекурсивный 
перебор. 
class Functor { 
// ‘Функция’ обратного вызова 
public: 
virtual void Apply(MotherOfAllClasses*) = 0; 
}; 
class MotherOfAllClasses { 
public: 
// 
Применить fn к каждому доступному объекту 
virtual void EachObject(Functor& fn); 
}; 
Функция 
EachObject()
вызывает 
fn.Apply(this)
, а затем вызывает 
EachObject()
для каждого 
внедренного объекта или объекта, на который указывает переменная класса. Кроме того, 
EachObject()
вызывает 
Base::EachObject()
для каждого базового класса, таким образом члены 
базового класса тоже включаются в перечисление. В зависимости от алгоритма в 
MotherOfAllClasses
можно включить бит признака, показывающий, что объект был рассмотрен 
ранее. Впрочем, как мы вскоре убедимся, иногда без этого можно обойтись. 
Итераторы 
Более удачное решение — организовать возвращение объектом итератора для всех внедренных 
объектов (включая базовые классы), в том числе и тех, на которые непосредственно ссылаются его 
переменные. 
class MOAOIterator { 
// “MotherOfAllObjectsIterator” 
public: 
virtual bool More() = 0; 
virtual MotherOfAllObjects* Next() = 0; 
}; 
class MotherOfAllObjects { 
public: 
virtual MOAOIterator* EachObject(); 
}; 



Download 1,95 Mb.

Do'stlaringiz bilan baham:
1   ...   130   131   132   133   134   135   136   137   ...   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