Информационный сайт

 

Реклама
bulletinsite.net -> Книги на сайте -> Программисту -> Янг Майкл Дж. -> "Visual С++ 6. Полное руководство: В 2 т.(том1)" -> 55

Visual С++ 6. Полное руководство: В 2 т.(том1) - Янг Майкл Дж.

Янг Майкл Дж. Visual С++ 6. Полное руководство: В 2 т.(том1) — Бином, 2006. — 569 c.
Скачать (прямая ссылка): vicualcc2006t1.djvu
Предыдущая << 1 .. 49 50 51 52 53 54 < 55 > 56 57 58 59 60 61 .. 204 >> Следующая

CCurrency Money (85, 25); // создание объекта Money.PrintAmount (); // печать его содержимого
Money = CCurrency (24, 65);// создание временного объекта и
// присваивание его существующему // объекту
Если стандартная операция присваивания для написанного класса не подходит, то следует перегрузить оператор присваивания. Например, рассмотрим класс CMessage, предназначенный для хранения и вывода сообщений:
#include <string.h> #include <iostream.h>
class CMessage {
private:
char "Buffer; // хранит строку сообщения
public:
CMessage() (
Buffer = new char('\0'); // инициализирует переменную
// Buffer пустой строкой
}
-CMessage () {
delete[]Buffer; // освобождает память
}
void Display() (
cout « Buffer « '\n'; // печатает сообщение }
void Set (char *String) // сохраняет новую строку сообщения {
delete [] Buffer;
Buffer = new char [strlen (String) + 1];
strcpy (Buffer, String);
}
};
Если один объект класса CMessage присвоить другому, то переменная-член Buffer обоих объектов будет указывать на один и тот же блок памяти. Если затем вызвать функцию-член Set для изменения сообщения, хранимого в одном объекте, то этот блок памяти освободится, вследствие чего в переменной Buffer другого объекта будет храниться указатель на случайные данные. То же самое произойдет, если один объект будет уничтожен раньше другого, так как деструктор освобождает блок памяти, на который указывает переменная Buffer.
Чтобы обеспечить корректное присваивание одного объекта класса CMessage другому, добавим в определение класса следующую функцию-оператор.
class CMessage {
// другие объявления: public:
void operator = (const CMessage SMessage) (
delete [] Buffer;
Buffer = new char [Strien (Message.Buffer) + 1] ;
strcpy (Buffer, Message.Buffer);
}
// другие объявления: }
В отличие от простого копирования адреса блока памяти, хранящегося в поле Buffer, из объекта-источника в объект-приемник, перегруженный оператор "=" создает совершенно новый блок памяти для объекта-приемника, а затем копирует строку в память. Таким образом, каждый объект имеет собственную копию строки.
После этого можно безопасно присвоить один объект класса CMessage другому так, как это делается в следующей программе.
void main () (
CMessage Messagel;
Messagel.Set ("initial Messagel message"); Messagel.Display ( );
CMessage Message2;
Message2.Set ("initial Message2 message"); Message2.Display ( );
Messagel = Message2; Messagel.Display ();
}
На печать будет выведено
initial Messagel message initial Message2 message initial Message2 message
Примечание
При перегрузке оператора "=" необходимо использовать функции-члены класса. Нельзя использовать дружественные функции, которые не являются членами класса.
Когда функция operator= определена указанным способом, в выражение можно включить только единственный оператор присваивания. Однако если эта функция возвращает ссылку на объект-приемник класса CMessage, как в следующем примере,
CMessage & operator= (const CMessage SMessage) (
delete [] Buffer;
Buffer = new char [strlen (Message.Buffer) + 1]; strcpy (Buffer, Message.Buffer) ; return *this; }
то в строке можно объединить несколько операторов присваивания.
void main () (
CMessage Messagel; CMessage Message2; CMessage Message3;
Messagel.Set ("hello") ; Message3 = Message2 = Messagel; }
Компилятор выполняет последовательные операции присваивания, продвигаясь справа налево. В данном примере первой вызывается функция-оператор "=", присваивающая объект Messagel объекту Message2. Она возвращает ссылку на Message2, содержащий копию строки "hello". Далее компилятор вызывает функцию-оператор, присваивающую ссылку на Mes s age 2 объекту Message3. В результате все три объекта класса CMessage имеют отдельные копии строки "hello". Обратите внимание: функция-оператор "=" может возвращать объект класса CMessage, а не ссылку на него. Однако при этом генерируется избыточная операция копирования и, следовательно, несколько снижается эффективность программы.
В окончательном варианте функции operator= должна быть предусмотрена защита от случайного вызова, присваивающего объект самому себе. Такое действие приведет к удалению содержимого буфера Buffer с последующей попыткой скопировать из него строку. Если объект присваивается самому себе, адрес объекта-источника (sMessage) будет таким же, как и адрес текущего объекта (this). Если функция определит, что выполняется самоприсваивание, то она сразу же должна возвратить значение, не выполняя операцию копирования.
CMessage & operator= (const CMessage SMessage) {
if (SMessage == this)
return *this; delete [] Buffer;
Buffer = new char [Strien (Message.Buffer) + 1]; strcpy (Buffer, Message.Buffer) ; return *this; }
Ниже приведен полный листинг класса CMessage с окончательной версией функции operators
#include <string.h> #include <iostream.h>
class CMessage {
private:
char *Buffer; // хранит строку сообщения
public :
CMessage() (
Buffer = new char ( ' \0' ) ; // инициализирует переменную
Предыдущая << 1 .. 49 50 51 52 53 54 < 55 > 56 57 58 59 60 61 .. 204 >> Следующая
Реклама
Авторские права © 2009 AdsNet. Все права защищены.
Rambler's Top100