Партнерка на США и Канаду по недвижимости, выплаты в крипто

  • 30% recurring commission
  • Выплаты в USDT
  • Вывод каждую неделю
  • Комиссия до 5 лет за каждого referral

3.3. Перегрузка операций

C++ позволяет переопределить действие большинства операций так, чтобы при использовании с объектами конкретного класса они выполняли заданные функции. Эта дает возможность использовать собственные типы данных так же, как стандартные. Обозначения собственных операций вводить нельзя.

Для перегрузки встроенных операторов можно использовать ключевое слово operator. Ему может быть присвоен ряд значений, зависящих от параметров. Таким образом, оператору типа + можно присвоить дополнительные значения. Это облегчает написание программ и делает их более читабельными.

vect oprator *(const vect &,const matix &)

где * является двухместным оператором умножения.

matix t; vect s, r; s=t*r; // s=mpy(r, t);
Перегруженный оператор можно вызвать и использованием функциональной формы записи: s=operator*(t, r);
Хотя операторам и могут добавляться новые значения, но их приоритет остается прежним. Например, операция умножения имеет более высокий приоритет, чем сложение.

Можно перегружать любые операции, существующие в C++, за исключением:

. .* ?: # ## sizeof

Доступны все арифметические, логические операторы, операторы сравнения, равенство, присвоение, операторы поразрядных операций, префиксные и постфиксные формы операторов приращения и декремента. могут быть перегружены операторы индексации “[]” и обращения к функции “()”. Также могут быть перегружены оператор указателя класса “->“ и оператор указателя на член “->*”. Возможна перегрузка new, delete.

Перегрузка операций осуществляется с помощью методов специального вида {функций-операций) и подчиняется правилам:

НЕ нашли? Не то? Что вы ищете?

• при перегрузке операций сохраняются количество аргументов, приоритеты операций и правила ассоциации (справа налево или слева направо), используемые в стандартных типах данных;

• для стандартных типов данных переопределять операции нельзя;

• функции-операции не могут иметь аргументов по умолчанию;

• функции-операции наследуются (за исключением =*);

• функции-операции не могут определяться как static.

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

Функция-операция содержит ключевое слово operator, за которым следует знак переопределяемой операции:

тип operator операция ( список параметров) { тело функции }

3.4. Перегрузка унарных и бинарных операций

Перегрузка унарных операций. Одноместные операторы типа “!”, “++”, “~” “[]”.

class clock

{

unsigned long sec;

public:

clock(unsigned long s):sec(s) { }

void tick() { sec++; }

clock operator++() { tick(); return *this; }

};

void main() { clock t(100); ++t; }

Этот класс перегружает префиксный оператор приращения ++. Перегруженный оператор представляет собой функцию-член. Перегруженный operator++() также обновляет неявную переменную clock и возвращает обновленное значение.

Префиксную операцию ++ можно перегрузить, используя friend-функцию.

frien clock operator++(clock &s1) { s1.tick(); return s1; }

Так как переменная clock должна увеличиваться мы передаем ее по ссылке. Решение о выборе между представлением friend и функцией-членом обычно зависит от того, насколько необходимы и доступны операторы неявного преобразования. Явная передача аргумента, как в friend-функции, позволяет автоматическое его приведение.

Операции инкремента и декримента могут быть перегружены как для префиксной, так и для постфиксной формы записи.
Префиксная форма объявляется как операция-член класса, которая не имеет аргументов, либо как дружественная операция, которая имеет один аргумент, представляющий собой ссылку на объект данного класса.
Постфиксная форма объявляется как операция-член класса, которая имеет один аргумент типа int, либо как дружественная операция, которая имеет два аргумента: ссылку на объект данного класса и аргумент типа int. Аргумент типа int на самом деле не используется. Фактически он имеет нулевое значение.

class X {

public:

X & operator ++(); //Префиксная форма

X & operator ++(int); // Постфиксная форма

};

class Y {

public:

friend Y & operator ++(Y &); //Префиксная форма

friend Y & operator ++(Y &,int); // Постфиксная форма

};

@x интерпретируется как x. opertor@(), если operator @ - функция-член и operator@(x), если operator @ - дружественная функция.

Унарная функция-операция, определяемая внутри класса, должна быть представлена с помощью нестатического метода без параметров, при этом операндом является вызвавший ее объект, например:

class monstrf

monstr & operator ++() {++health: return *this:}

}:

monstr Vasia;

cout « (++Vasia).get_health();

Если функция определяется вне класса, она должна иметь один параметр типа класса:

class monstr{

friend monstr & operator ++( monstr &M);

}:

monstr& operator ++(monstr &M) {++M. health; return M;}

Если не описывать функцию внутри класса как дружественную, нужно учитывать доступность изменяемых полей. В данном случае поле health недоступно извне, так как описано со спецификатором private, поэтому для его изменения требуется использование соответствующего метода. Введем в описание класса monstr метод change_health, позволяющий изменить значение поля health

void change__health(int he){ health = he;}

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

monstr& operator ++(monstr &М){

int h = M. get__health(); h++;

M. change_health(h);

return М:}

Операции постфиксного инкремента и декремента должны иметь первый параметр типа int. Он используется только для того, чтобы отличить их от префиксной формы:

class monstrj

monstr operator ++(int){

monstr MCnhis); health++;

return M;

}

}:

monstr Vasia:

cout « (Vas1a++).get_health();

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

class monstr{

bool operator >(const monstr &M){

1f( health > M. health) return true;

return false:

Если функция определяется вне класса, она должна иметь два параметра типа класса:

bool operator >(const monstr &M1. const monstr &M2){

1f( Ml. get_health() > M2.get_health()) return true:

return false:

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

class clock {

friend clock operator+(const clock &c1,const clock &c2) ;

};

clock operator+(const clock &c1,const clock &c2) {

clock temp(c1.sec+c2.sec); return temp;

}

Оба параметра явно определяются и являются кандидатами для преобразования назначением. Используя это определение имеем:

int i=5; clock c(100);

c+i; // допустимо: i - преобразуется в clock

i+c; // допустимо: i - преобразуется в clock

В противоположность этому, перегрузим двухместный - функцией-членом.

class clock {

clock operator -(const clock &c) { clock temp(sec-c. sec); return temp; } };

Существует первый неявный аргумент. В него попадает некоторый используемый параметр. Это может вызвать асимметричное поведение двухместных операторов.

int i=5; clock c(100);

c-i; // допустимо i преобразуется в clock; c.operator-(i)

i-c; // недопустимо i не относится к типу clock; i. operator-(c)

Определим операцию умножения: long и clock

clock operator *(long m, const clock &c) {

clock temp(m*c. sec); return temp;

Такая реализация вынуждает операцию умножения иметь фиксированный порядок выполнения, зависящий от типа. Для избежания этого обычно пишется второй перегруженный функциональный оператор.

clock operator *(const clock &c, long m) {

clock temp(m*c. sec); return temp;}

*****@***интерпретируется как y. opertor@(x), если operator @ - функция-член и operator@(y, x), если operator @ - дружественная функция.

4. Перегрузка операций

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

Операция присваивания определена в любом классе по умолчанию как поэлементное копирование. Эта операция вызывается каждый раз, когда одному существующему объекту присваивается значение другого. Если класс содержит поля, память под которые выделяется динамически, необходимо определить собственную операцию присваивания. Чтобы сохранить семантику присваивания, операция-функция должна возвращать ссылку на объект, для которого она вызвана, и принимать в качестве параметра единственный аргумент — ссылку на присваиваемый объект.

const monstr& operator = (const monstr &M){

/ / Проверка на самоприсваивание:

1f (&М == this) return n h i s:

i f (name) delete [ ] name;

i f (M. name){

name = new char [strlen(M. name) + 1];

Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18