Главная Случайная страница


Полезное:

Как сделать разговор полезным и приятным Как сделать объемную звезду своими руками Как сделать то, что делать не хочется? Как сделать погремушку Как сделать так чтобы женщины сами знакомились с вами Как сделать идею коммерческой Как сделать хорошую растяжку ног? Как сделать наш разум здоровым? Как сделать, чтобы люди обманывали меньше Вопрос 4. Как сделать так, чтобы вас уважали и ценили? Как сделать лучше себе и другим людям Как сделать свидание интересным?


Категории:

АрхитектураАстрономияБиологияГеографияГеологияИнформатикаИскусствоИсторияКулинарияКультураМаркетингМатематикаМедицинаМенеджментОхрана трудаПравоПроизводствоПсихологияРелигияСоциологияСпортТехникаФизикаФилософияХимияЭкологияЭкономикаЭлектроника






Перегрузка операции присваивания





Присваивание и инициализация - различные действия. Инициализация - выполняется при создании объекта, при этом вновь созданный объект получает инициализирующее значение. При присваивании - происходит копирование данных из одного объекта в другой.

Операция присваивания (=) предопределена языком для любого пользовательского типа, т.е. если пользователь не перегрузил эту операцию, она все равно работает, но в этом случае это поэлементное копирование. Такое присваивание подходит, если память под член-данные не выделяется динамически.

Пример.

class String

{int sz;

char *str;

public:

String (int s)

{str=new char[sz=s];}

~String() {delete []str;}

};

void main ()

{

String a(10); // Это описание объекта а и его

//инициализация, т.е. передача конструктору

// инициализирующею значения 10.

String b(30);

// Описание и инициализация объекта b

a=b; // Присваивание объекта b объекту а.

}

Оба объекта указывают на одну область, так как продублирован и указатель. При вызове деструктора окажется освобожденной динамическая память и для другого объекта. При попытке вызова деструктора для второго объекта последствия непредсказуемы, так как это попытка освободить уже свободную область. Ясно, что предопределенное присваивание не подходит и следует перегрузить операцию присваивания.

Перегрузка операции присваивания отличается тремя особенностями:

1. операция не наследуется;

2. операция определена по умолчанию для каждого класса в качестве операции поразрядного копирования объекта, стоящего справа от знака операции, в объект стоящий слева.

3. операция может перегружаться только в области определения класса. Это гарантирует, что первым операндом всегда будет леводопустимое выражение.

Формат перегруженной операции присваивания:

имя_класса &operator =(имя_класса&);

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

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

Таким образом, перегруженная операция присваивания x1=x2 должна выполнить следующие действия:

1. освободить всю память для объекта х1 (если она была выделена при конструировании объекта);

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

3. выполнить копирование член-данных х2 в член-данные x1.

Существует два случая, когда подобная операция присваивания будет выводить плохие результаты:

1. при копировании объекта самого в себя, в этом случае при перегрузке операции проверяется наличие подобной ситуации;

2.при инициализации объекта другим объектом, в этом случае создается специальный конструктор для копирования, так как неинициализированному объекту операция присваивания не применяется. Этот конструктор имеет вид Type(const Туре &)

Пример.

Сlass String

{int sz;

char *str;

public:

String(int s)

{str=new char[sz = s];}

String (const String&);

// Это конструктор копирования

~String()

{delete []str;}

String &operator=(const String&);

};

String:: String(const String &l)

{str=new char[sz=l.sz];

strcpy(str, l.str);

}

String & String:: operator=(const String& l)

{if (this!=&l) // Нет ли копирования объекта

// самого в себя

{delete[]str;

str=new char[sz=l.sz];

strcpy(str, l.str);

}

return *this;

}

Таким образом, в общем случае для выполнения операции присваивания и инициализации для объектов класса Туре необходимо две функции:

class Type

{...

public:

Type(const Type&);

// конструктор для копирования

Type operator=(const Type&);

// доопределение присваивания

};

Функция operator= может определяться только как нестатический член класса X. Обращение к этой функции выполняется в следующей форме

objX=obj,

где objX - объект класса X, obj - параметр, передаваемый функции operator. Выражение objX=obj интерпретируется как objX.operator(obj).

Date: 2016-05-13; view: 681; Нарушение авторских прав; Помощь в написании работы --> СЮДА...



mydocx.ru - 2015-2024 year. (0.007 sec.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав - Пожаловаться на публикацию