Программирование >>  Программирование на языке c++ 

1 ... 63 64 65 [ 66 ] 67 68 69 ... 159


operator float{) { return f; }

void f(A aa)

{ cout aa endl; } void f(double dd) { cout dd endl; ) void main(void)

{ f(1.45); Стандартное преобразование. Результат: 1.45 f(O); Стандартное преобразование. Результат: 48 А а(2.34); Объявление объекта а класса А f(a); Результат: 2.34

cout а endl; Результат: 2.34

5.5. Присваивание и инициализация

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

void function(void)

{ string str1(30); это описание объекта strl и

инициализация этого объекта tnepeAa4a соответствуюидему конструктору инициали- зируюидего значения 30) string str2{50); это описание и инициализация

объекта str2 strl = str2; это присваивание объекта str2 объекту strl

При выполнении операции присваивания (см. последнее выражение) необходимо: -♦ освободить всю динамически выделенную память для объекта strl (конечно, если она была выделена при конструировании объекта);



-♦ выделить (динамически) память под компоненты-данные объекта stri в соответствии с размерами этих компонентов, полученными из объекта str2 (опять же, если это необходимо);

-♦ осуществить копирование значений компонентов-данных объекта str2 в компоненты-данные объекта stri. Рассмотрим другой пример: void function(void)

{ string stri(30); инициализация string str2=str1; здесь тоже выполняется инициализация

В этом случае объект str2 еще не сконструирован. Для того чтобы его сконструировать (инициализировать), берутся значения из уже сконструированного объекта stri. Рассмотрим теперь класс string:

class string {

char* pointer to string;

unsigned size; public:

string(unsigned s) { pointer to string=new char[size=s]; } -stringO { delete[] pointer to string; }

Возьмем строки stri и str2 из первого примера, которые были инициализированы значениями 30 и 50. В этом случае выражение:

str1 = str2;

будет ошибочным, поскольку значение strl.pointer to string изменится на значение str2.pointer to string и мы получим два указателя на одну и ту же область памяти (см. также рис. 1.6). При завершении функции function соответствующий деструктор будет вызван дважды, и он дважды освободит одну и ту же память, что является грубой ошибкой. Правильное решение этой задачи заключается в доопределении оператора = (присваивания). При этом на него возлагаются все дополнительные действия, которые необходимо выполнить (они были перечислены в начале этого параграфа). Заметим, что опера-



тор присваивания можно доопределить только как нестатическую компонент-функцию. В результате наш класс будет представлен в виде:

class string {

char* pointer to string;

unsigned size; public:

string(unsigned s) { pointer to string=new char[size=s];} ~string() { delete[] pointer to string;} string& operator=(const string&);

string& string::operator=(const string& str) { if (this != &str) нет ли копирования строки в саму себя { delete[] pointer to string; освобождение старой

памяти

pointer to string=new char[size=str.size]; выделение

новой памяти strcpy(pointer to string,str.pointer to string); копирование строки str.pointer to string в строку pointer to string }

return *this;

Рассмотрим объявление

string& operator=(const string&);

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

string& operator=(string& str1,const string& str2) {.....}

Если объекты strl и str2 занимают большое место в памяти, то объявление функции в виде



1 ... 63 64 65 [ 66 ] 67 68 69 ... 159

© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки.
Яндекс.Метрика