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



Download 1,95 Mb.
Pdf ko'rish
bet38/144
Sana24.02.2022
Hajmi1,95 Mb.
#223123
TuriРеферат
1   ...   34   35   36   37   38   39   40   41   ...   144
Bog'liq
C -Eldjer-Djeff-for-Real-Programmers-RUS-www.itlibitum.ru

 
53 
}; 
void* operator new(size_t bytes, Pool* p) 

return 
p->Allocate(bytes); 

extern Pool* DefaultPool; 
Foo* f = new(DefaultPool) Foo; 
Дополнительные аргументы указываются между ключевым словом new и перед именем класса 
Foo

они передаются перегруженному оператору после размера блока, предоставленного компилятором. 
Оператор delete 
Оператор 
delete
обычно перегружается вместе с оператором new для выполнения нестандартных 
операций управления памятью. Существуют два интерфейса, автоматически вызываемые 
компилятором при удалении объекта: 
1. void operator delete(void* address); 
2. void operator delete(void* address, size_t bytes); 
Первая версия просто передает вам адрес освобождаемого блока; чтобы определить его размер, вам 
придется самостоятельно заглянуть в хрустальный шар. Вторая версия вроде бы передает размер 
освобождаемого блока, но... он может быть меньше истинного размера! Проблемы возникают в 
следующих ситуациях: 
class Foo { 
private: 
int 
x; 
public: 
~Foo(); 
// 
Невиртуальный деструктор 
}; 
class Bar : public Foo { 
private: 
int 
y; 
public: 
~Bar(); 
}; 
Bar* b = new Bar; 
delete b; // 
Правильный размер 
Foo* f = new Bar; 
delete f; // 
Размер Foo, а не Bar 
Компилятор определяет размер на основании вызываемого деструктора. Если невиртуальный 
деструктор вызывается для указателя на базовый класс, используется размер базового класса. 
Правильный размер будет передаваться при соблюдении любого из трех условий: 
1. Деструктор является виртуальным. 
2. Указатель ссылается на настоящий тип объекта. 
3. Тип, на который ссылается указатель, имеет тот же размер, что и настоящий тип. 
Последнее условие соблюдается лишь в том случае, если в производном классе не добавляется ни 
одной новой переменной, а базовый и производный классы одновременно либо содержат, либо не 
содержат виртуальных функций (и как следствие, указателей v-таблицы). Непонятно? Тогда запомните 
простое правило — объявляйте ваши деструкторы виртуальными. 
Оператор 
delete
, как и оператор 
new
, можно перегружать как в форме функции класса, так и в форме 
внешней функции. Если оператор перегружается функцией класса, он наследуется. В отличие от 


 54 
оператора 
new
, для оператора 
delete
нельзя создавать дополнительные сигнатуры. Два варианта, 
приведенные выше, — это все, что у вас есть. 


Шаблоны и 
безопасность 
типов 
Хотя стандарты шаблонов опубликованы уже давно, они все еще распространены недостаточно 
широко. Конечно, трудно использовать нечто, не поддерживаемое вашим компилятором, — наверное, 
это первая причина, по которой большинство программистов C++ не умеет работать с шаблонами. К 
счастью, сейчас все основные компиляторы уже вошли в двадцатый век, так что эта проблема уже 
отпала. Остается лишь понять, что такое шаблон, как обойти все синтаксические ловушки, но прежде 
всего — для чего он все-таки нужен. Эта глава не ограничивается обзором синтаксиса. В ней также 
рассматриваются основы безопасности типов в C++, причем особое внимание уделяется шаблонам. 
Что такое шаблоны и зачем они нужны? 
Интерфейс простого класса-коллекции (на примере связанного списка) выглядит так: 
class ListNode { 
private: 
ListNode* 
next; 
void* 
data; 
public: 
ListNode(void* d, ListNode* n = NULL) : next(n), data(d) {} 
~ListNode() { delete next; } 
void* Data() { return data; } 
ListNode* Next() { return next; } 
}; 
Заметили что-нибудь особенное? 
Проблемы 
Прежде всего, в глаза бросаются все эти 
void*
. И вы, и я прекрасно знаем, что на самом деле за ними 
кроется нечто совершенно иное. Где-то в клиентском коде придется сделать что-нибудь подобное: 
for (ListNode* n = listHead; n != NULL; n = n->Next()) 
f((Foo*)n->Data()); 
Иначе говоря, вам придется постоянно приводить 
void*
к конкретному типу Но как убедиться в том, 
что полученный указатель действительно имеет тип 
Foo*
? Здесь придется рассчитывать только на 
себя, потому что компилятор со словами «Надеюсь, ты знаешь, что делаешь» умывает руки. Допустим, 
вы уверены, что ваше использование класса надежно по отношению к типам. Но можно ли 
гарантировать, что другой программист не выкинет какую-нибудь глупость и не занесет в коллекцию 
объект другого типа? Если вы свято верите в это, я рекомендую держаться подальше от рискованных 
инвестиций и вложить деньги в правительственные бумаги, вряд ли вам повезет в этой жизни. 

Download 1,95 Mb.

Do'stlaringiz bilan baham:
1   ...   34   35   36   37   38   39   40   41   ...   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