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



Download 1,95 Mb.
Pdf ko'rish
bet52/144
Sana24.02.2022
Hajmi1,95 Mb.
#223123
TuriРеферат
1   ...   48   49   50   51   52   53   54   55   ...   144
Bog'liq
C -Eldjer-Djeff-for-Real-Programmers-RUS-www.itlibitum.ru

 
81 
Ведение статистики класса 
Также несложно организовать накопление статистики об использовании операторов 
Type*
и 
->
в 
статических переменных параметризованного класса. 
template  
class SPCS { 
private: 
Type* 
pointer; 
static 
int 
conversions; 
static 
int 
members; 
public: 
SPCS() : pointer(NULL) {} 
SPCS(Type* p) : pointer(p) {} 
operator Type*() { conversions++; return pointer; } 
Type* operator->() { members++; return pointer; } 
int Conversions() { return conversions; } 
int Members() { return members; } 
}; 
Глобальные переменные должны быть где-то определены. Обычно это делается в файле Foo.cpp: 
// В файле Foo.cpp 
int Ptr::conversions = 0; 
int Ptr::members = 0; 
Разумеется, вы можете воспользоваться директивами 
#ifdef
, чтобы это относилось только к 
отладочной версии. 
Ведение статистики объекта 
Мы подошли к более сложной теме. Возможно, ее следует отложить до знакомства с ведущими 
указателями (master pointers), однако умные указатели также могут вести статистику по отдельным 
объектам, а не по классу в целом. Задача не сводится к тому, чтобы сделать только что показанные 
переменные нестатическими (то есть по одному экземпляру переменных на указатель), поскольку мы 
(пока) не можем обеспечить однозначное соответствие между указателями и объектами. Вместо этого 
статистику придется хранить в самих объектах. Ниже приведен полезный вспомогательный класс, 
который можно создать на основе множественного наследования как производный от класса 
указываемого объекта и от класса умного указателя, знающего о его свойствах. Объявляя указатель 
другом, вы предоставляете ему доступ к защищенным членам классов, производных от 
Counter

class Counter { 
protected: 
Counter() : conversions(0), members(0) {} 
Counter(const Counter&) : conversions(0), members(0) {} 
Counter& operator=(const Counter&) { return *this; } 
public: 
int 
conversions; 
int 
members; 
int Conversions() { return conversions; } 
int Members() { return members; } 
}; 
template  
class SPOP { 
private: 
Type* 
pointer; 


 82 
public: 
SPOS() : pointer(NULL) {} 
SPOP(Type* f) : pointer(f) {} 
operator Type*() { pointer->conversions++; return pointer; } 
Type* operator->() { pointer->members++; return pointer; } 
}; 
На эту тему существует ряд вариаций, с некоторыми из них мы познакомимся при изучении ведущих 
указателей. 
Кэширование 
Иногда нельзя даже настаивать, чтобы объект физически находился в памяти все время, пока к нему 
нужен доступ. В следующем примере предполагается, что функция 
ReadObject()
умеет использовать 
данные о местонахождении объекта на диске, чтобы создать экземпляр и занести его адрес в указатель 
pointer
. Если при вызове операторов объект отсутствует в памяти, он автоматически считывается с 
диска. 
typedef unsigned long DiskAddress; // Заменить нужными данными 
template  
class CP { 
private: 
DiskAddress 
record_number; 
Type* 
pointer; 
void 
ReadObject(); 
// 
Считывает объект с диска 
public: 
CP(DiskAddress da) : pointer(NULL), record_number(da) {} 
CP(Type* f) : pointer(f), record_number(f->RecordNumber()) {} 
operator 
Type*() 

if (pointer == NULL) this->ReadObject(); 
return 
pointer; 

Type* 
operator->() 

if (pointer == NULL) this->ReadObject(); 
return 
pointer; 

}; 
Подробно говорить о кэшировании преждевременно, поскольку приходится учитывать множество 
проблем, к которым мы еще не готовы. Если вы хотите гарантировать, что читается лишь одна копия 
объекта независимо от того, сколько различных объектов на нее ссылается, или чтобы объект 
уничтожался сразу после завершения работы операторов, вам придется подождать следующих глав, 
посвященных ведущим указателям и управлению памятью. Тем не менее, в простых ситуациях с одним 
считыванием, в которых может существовать несколько копий объекта, такая методика достаточно 
хорошо работает и с простыми умными указателями. 
Кэширующие указатели используют один распространенный прием — они экономят несколько бит за 
счет объединения дискового адреса и адреса памяти в одной переменной класса. При этом 
используются два упрощающих предположения: 
1. Размер адреса памяти не более чем на один бит превышает размер дискового адреса. 
2. Средства управления памятью, используемые оператором 
new
, никогда не возвращают 
нечетный адрес. 



Download 1,95 Mb.

Do'stlaringiz bilan baham:
1   ...   48   49   50   51   52   53   54   55   ...   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