|
Программирование >> Программирование на языке c++
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 занимают большое место в памяти, то объявление функции в виде
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки. |