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



Download 1,95 Mb.
Pdf ko'rish
bet22/144
Sana24.02.2022
Hajmi1,95 Mb.
#223123
TuriРеферат
1   ...   18   19   20   21   22   23   24   25   ...   144
Bog'liq
C -Eldjer-Djeff-for-Real-Programmers-RUS-www.itlibitum.ru

 
23 
нарушает ваш пуританский стиль кодирования. Мораль: константные функции классов нужно 
использовать либо с полным фанатизмом (желательно), либо не использовать вовсе. 
Стековые и динамические объекты 
Иногда мне кажется, что C++ лучше изучать без предварительного знакомства с C. В C++ часто 
используются те же термины, что и в С, но за ними кроются совершенно иной смысл и правила 
применения. Например, возьмем примитивный целый тип. 
int x = 17; 
В C++ это будет экземпляр встроенного «класса» 
int
. В С это будет... просто 
int
. Встроенные классы 
имеют свои конструкторы. У класса 
int
есть конструктор с одним аргументом, который 
инициализирует объект передаваемым значением. Теоретически существует и деструктор, хотя он 
ничего не делает и ликвидируется всеми нормальными разработчиками компиляторов в процессе 
оптимизации. Важно осознать, что встроенные типы за очень редкими исключениями подчиняются тем 
же базовым правилам, что и ваши расширенные типы. 
Вы должны понимать эту теоретическую особенность C++, чтобы правильно относиться к стековым и 
динамическим объектам и связанным с ними переменным. 
Размещение в стеке 
Чтобы выделить память для стековой переменной в области действия блока, достаточно просто 
объявить ее обычным образом. 

int 
i; 
foo 
f(constructor_args); 
// 
Перед выходом из блока вызываются деструкторы i и f 

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

int 
i; 
foo 
f; 
SomeFunction(&f); 

Без изучения функции 
SomeFunction
невозможно сказать, безопасен ли этот фрагмент. 
SomeFunction
может передать адрес дальше или сохранить его в какой-нибудь переменной, а по 
закону Мэрфи этот адрес наверняка будет использован уже после уничтожения объекта 
f
. Даже если 
сверхтщательный анализ 
SomeFunction
покажет, что адрес не сохраняется после вызова, через пару 
лет какой-нибудь новый программист модифицирует 
SomeFunction
, продлит существование адреса 
на пару машинных команд и — БУМ!!! Лучше полностью исключить такую возможность и не 
передавать адреса стековых объектов. 
Динамическое размещение 
Чтобы выделить память для объекта в куче (heap), воспользуйтесь оператором 
new
new
new
new

foo* f = new foo(constructor_args); 
Вроде бы все просто. Оператор 
new
выделяет память и вызывает соответствующий конструктор на 
основании переданных аргументов. Но когда этот объект уничтожается? Подробный ответ на этот 
вопрос займет примерно треть книги, но я не буду вдаваться в технические детали и отвечу так: «Когда 


 24 
кто-нибудь вызовет оператор 
delete
для его адреса». Сам по себе объект из памяти не удалится; вы 
должны явно сообщить своей программе, когда его следует уничтожить. 
Указатели и ссылки 
Попытки связать указатели с динамическими объектами часто приводят к недоразумениям. В 
сущности, они не имеют друг с другом ничего общего. Вы можете получить адрес стекового объекта и 
выполнить обратное преобразование, то есть разыменование (dereferencing) адреса динамического 
объекта. И на то, и на другое можно создать ссылку. 

foo 
f; 
foo* p = &f; 
f.MemberFn(); 
// 
Использует сам объект 
p->MemberFn(); 
// 
Использует его адрес 
p = new foo; 
foo& r = *p;
// Ссылка на объект 
r.MemberFn(); 
// 
То же, что и p->MemberFn() 

Как видите, выбор оператора 
.
или 
->
зависит от типа переменной и не имеет отношения к атрибутам 
самого объекта. Раз уж мы заговорили об этом, правильные названия этих операторов (
.
и 
->
) — 
селекторы членов класса (member selectors). Если вы назовете их «точкой» или «стрелкой» на семинаре 
с коктейлями, наступит гробовая тишина, все повернутся и презрительно посмотрят на вас, а в дальнем 
углу кто-нибудь выронит свой бокал. 
Недостатки стековых объектов 
Если использовать оператор 
delete
для стекового объекта, то при большом везении ваша программа 
просто грохнется. А если вам (как и большинству из нас) не повезет, то программа начнет вести себя, 
как ревнивая любовница — она будет вытворять, всякие гадости в разных местах памяти, но не скажет, 
на что же она разозлилась. Дело в том, что в большинстве реализаций C++ оператор 
new
записывает 
пару скрытых байтов перед возвращаемым адресом. В этих байтах указывается размер выделенного 
блока. По ним оператор 
delete
определяет, сколько памяти за указанным адресом следует освободить. 
При выделении памяти под стековые объекты оператор 
new
не вызывается, поэтому эти 
дополнительные данные отсутствуют. Если вызвать оператор 
delete
для стекового объекта, он 
возьмет содержимое стека над вашей переменной и интерпретирует его как размер освобождаемого 
блока. 
Итак, мы знаем по крайней мере две причины, по которым следует избегать стековых объектов — если 
у вас нет действительно веских доводов в их пользу: 
1. Адрес стекового объекта может быть сохранен и использован после выхода за границы области 
действия объекта. 
2. Адрес стекового объекта может быть передан оператору 
delete

Следовательно, для стековых объектов действует хорошее правило: Никогда не получайте их адреса 
или адреса их членов. 
Достоинства стековых объектов 
С другой стороны, память в стеке выделяется с головокружительной быстротой — так же быстро, как 
компилятор выделяет память под другие автоматические переменные (скажем, целые). Оператор 
new
(по крайней мере, его стандартная версия) тратит несколько тактов на то, чтобы решить, откуда взять 
блок памяти и где оставить данные для его последующего освобождения. Быстродействие — одна из 
веских причин в пользу выделения памяти из стека. Как вы вскоре убедитесь, существует немало 
способов ускорить работу оператора 
new
, так что эта причина менее важна, чем может показаться с 
первого взгляда. 



Download 1,95 Mb.

Do'stlaringiz bilan baham:
1   ...   18   19   20   21   22   23   24   25   ...   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