05.09.2016 Views

Стефан Р. - С++ Для чайников

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Класс Name содержит ресурсы, созданные специально для использования в этом<br />

объекте, а именно блок памяти, на который указывает pName. Это легко увидеть, посмотрев<br />

код конструкторов класса. Каждый из них (кроме конструктора по умолчанию)<br />

вызывает функцию copyName ().<br />

// copyName — копирует исходную строку pN в локально<br />

// выделенный блок памяти<br />

voici copyName (char J pN)<br />

{<br />

int length = strlen(pN) + 1;<br />

pName = new char[lengthj;<br />

strncpy(pName, pN, length);<br />

}<br />

Обратите внимание на то, как функция выделяет место в памяти под строку,<br />

равную длине исходной, а затем копирует содержимое pN в созданную строку 19 .<br />

При почленном копировании получается два объекта класса Name, указывающих<br />

на один и тот же фрагмент в памяти, а потому использование этого метода может<br />

легко привести к большим проблемам (например, что произойдет при удалении одного<br />

из объектов?).<br />

Оператор присвоения класса Name во избежание утечки памяти сначала должен освободить<br />

блок, на который указывает рКате (с помощью вызова функции deleteName{)),<br />

а затем запросить новый фрагмент с помощью функции copyName ().<br />

Такой метод и называется глубоким копированием.<br />

Почленный подход к С<br />

Заметьте, что я был очень точен и всегда говорил "почленное копирование". Я избегал<br />

упрощенного и неопределенного термина "копирование", поскольку он означает<br />

примитивное побитовое копирование.<br />

Смысл почленного копирования не очевиден, пока вы не обратитесь к классам,<br />

которые содержат в качестве членов объекты другого класса,<br />

class MyClass<br />

{<br />

public:<br />

Name name;<br />

int age;<br />

MyClass(char* pName, int newAge) : name(pName )<br />

(<br />

age = newAge;<br />

void fn()<br />

{<br />

MyClass a f"Kinsey", 16);<br />

MyClass bfChrista", 1);<br />

a - b;<br />

}<br />

(Если вы до сих пор незнакомы с синтаксисом инициализации : name fpName), самое<br />

время вернуться к главе 18, "Аргументация конструирования".)<br />

19<br />

В принципе в случае, когда новое имя не длиннее старого, мы могли бы обойтись без<br />

освобождения памяти и выделения новой, просто перезаписав новое имя на место старого<br />

(ценой этого упрощения было бы несколько неэкономное использование памяти программой).<br />

— Прим. ред.<br />

282 Часть V. Полезные особенности

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!