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



Download 1,95 Mb.
Pdf ko'rish
bet82/144
Sana24.02.2022
Hajmi1,95 Mb.
#223123
TuriРеферат
1   ...   78   79   80   81   82   83   84   85   ...   144
Bog'liq
C -Eldjer-Djeff-for-Real-Programmers-RUS-www.itlibitum.ru

 
141 


void 
Rollback() 
// 
Вернуться к самому старому образу 

Type* old = history.Pop(); 
Type* oldere = NULL; 
if (old != NULL) { // Хотя бы один раз 
while ((older = history.Pop()) != NULL) { 
delete 
old; 
old 

older; 

delete 
current; 
current 

old; 


Type* operator->() const { return current; } 
}; 
Хранение отдельного стека в каждом указателе оправданно для транзакций, в которых участвует 
небольшое количество объектов. Но если одной транзакции приходится отслеживать множество 
обновляемых объектов, кучу мелких стеков лучше объединить в один большой. Мы сделаем это 
позднее, когда речь пойдет о транзакциях. 
Образы автоматических объектов 
Концепцию образа можно немного обобщить, чтобы она распространялась не только на объекты, 
созданные оператором 
new
и обслуживаемые 
*
-указателями, но и автоматические объекты. 
Автоматическими считаются стековые объекты, а также переменные и компоненты базовых классов 
вмещающего объекта независимо от того, выделялась память под вмещающий объект динамически или 
нет. 
template  
class AutoImage { 
private: 
Type 
current; 
Type 
image; 
bool 
have_image; 
// 
Истина, если образ существует 
public: 
AutoImage() : have_image(false) {} 
AutoImage(const 
AutoImage
ai) 
: current(ai.current), image(), have_image(false) {} 
AutoImage& operator=(const AutoImage& ip) 

if (this != &ip) { 
current 

ip.current; 
have_image 

false; 

return 
*this; 

AutoImage& operator=(const Type& t) 

current = t; 


 142 
return 
*this; 

operator Type&() { return current; } 
void 
Snapshot() 

image 

current; 
have_image 

true; 

void Commit() { have_image = false; } 
void 
Rollback() 

current = image; 
have_image 

false; 

bool HaveImage() { return have_image; } 
}; 
Этот шаблон работает со всеми классами, которые удовлетворяют двум условиям: 
1. Тип, используемый в качестве параметра, имеет конструктор без аргументов. Он используется в 
конструкторе 
AutoImage
для инициализации 
current
и 
image

2. Тип, используемый в качестве параметра, допускает присваивание с помощью оператора 
=
по 
умолчанию, предоставленного компилятором, или перегруженного варианта для данного типа. 
Используется в функциях 
Shapshot()
и 
Rollback()

Все встроенные типы (такие как 
int
и 
double
) удовлетворяют этим условиям. Подходят и другие 
классы, имеющие конструктор без аргументов и рабочий оператор 
=
. Чем дольше я имею дело с C++, 
тем чаще мне кажется, что нарушение этих требований — проявление злостного непрофессионализма, 
за которое следует наказывать парой лет каторжного программирования на BASIC. Заодно я бы издал 
закон о том, чтобы конструкторы копий всегда работали так, как им положено. 
Конструктор копий 
AutoImage
следует примеру 
ImagePtr
и 
ImageStackPtr
— он использует 
конструктор без аргументов для создания фиктивного объекта 
image
и присваивает 
have_image
значение 
false
. Оператор 
=
делает то же самое, однако в нем не удается найти удобный способ 
уничтожить объект переменной 
image
. Мы выбираем меньшее из двух зол — объект остается без 
изменений и попросту игнорируется, поскольку переменная 
have_image
равна 
false
. Если вас это не 
устраивает и вы действительно хотите оставить объект 
image
неинициализированным до тех пор, пока 
в нем не появится настоящий образ, и уничтожить его после присвоения 
false
переменной 
have_image
, имеются два возможных решения: 
1. Изменить тип 
image
с 
Type
на 
Type*
и выделять для него память оператором 
new
. Это 
увеличит накладные расходы по сравнению с автоматическими объектами, однако вы сможете 
в полной мере контролировать процесс создания и уничтожения. 
2. Воспользоваться идиомой «виртуальных конструкторов» из главы 13. Не вдаваясь в 
подробности, скажу, что это позволит вам объявить 
image
чем-то приятным для глаза — 
например, 
unsigned char image(sizeof Type)
— нежели вызывать конструктор и 
деструктор Type вручную. Компиляторы С++ недолюбливают подобные фокусы, поэтому, 
прежде чем пускаться на авантюры, внимательно прочитайте главу 13. 
Если 
AutoImage
будет использоваться только для структур или классов, добавьте оператор 
->

Type* operator->() { return ¤t; } 
Обратите внимание: в отличие от предыдущих версий 
->
этот оператор не может быть константной 
функцией, поскольку 
current
находится внутри 
*this
и мы не можем гарантировать, что 
->
не будет 
использоваться для обращений к неконстантным функциям 
current




Download 1,95 Mb.

Do'stlaringiz bilan baham:
1   ...   78   79   80   81   82   83   84   85   ...   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