Перегрузка бинарных операторов
тип operator #(тип&)
Бинарные операторы:
· Арифметические операторы( a+b , a-b)
· Присваивание арифметических действий( + =, - =)
· Сравнения (= =, > , < , <=, >=)
· Логические (&&, ||)
· Запятая (a,b – выполняются слева направо)
При перегрузке оператора нельзя:
· перегрузить операторы, аргументами которых являются только встроенные типы данных
· изменить приоритет выполнения оператора
· изменить количество операндов оператора
· задать операторную функцию с аргументами по умолчанию
Особенности передачи и возврата параметров операторами:
· Операнды в оператор лучше передавать по ссылке – при этом нет вызова конструктора копирования как при передаче по значению
· Передача и возврат ссылок на константу позволяет контролировать модификацию объектов
· Если оператор не должен менять сам объект, то операторную функцию нужно задать константной
· Если требуется использовать возвращаемое значение для последующего вызова в цепочке других методов, то нужно вернуть ссылку на объект, т.к. возврат по значению не предусматривает таких действий
class example
{
private:
int a;
public:
example() { a = 0; }
example(int A) { a = A; }
example(example &A) {a = A.a;}
example operator + (example & A)
{
example temp;
temp.a = this->a + A.a;
return temp;
}
example operator - (int A)
{
example temp;
temp.a = this->a - A;
return temp;
}
bool operator == (example & A)
{
return a == A.a;
}
example& operator , (example & A)
{
if (a < A.a) return *this;
return A;
}
};
18. Перегрузка оператора =
тип& operator = (тип&);
Операция присваивания отличается от конструктора копирования тем, что должна очищать данные цели присваивания, тогда как конструктор копирования присваивает значения неинициализированным данным. Оператор присваивания генерируется автоматически компилятором в случае, если нет явного объявления программистом. Код, сгенерированный компилятором в данном случае, выполняет поверхностное побитовое копирование.
При перегрузке возвращаемый тип должен иметь тип класса для возможности реализации цепочек присваивания (a = b = c;). Обязательно необходима проверка на самоприсваивание. При работе динамическими ресурсами необходимо выделить память под новые данные и скопировать туда полученные данные, удалить старые данные, присвоить объекту значения нового ресурса. Оператор присваивания нельзя перегружать вне класса, т.к. определение оператора присваивания в глобальном виде сделало бы возможным переопределение стандартного поведения оператора =
class example
{
private:
int a;
public:
example() {}
example(int a) { this->a = a; }
~example() {}
int getInt() { return a; }
example & operator = (example &E)
{
if(this != &E)
{
this->a=E.getInt();
}
return *this;
}
};
19. Перегрузка операторов ввода/вывода (>>, <<)
ostream& operator << (ostream &, тип);
Перегрузка данного оператора осуществляется вне класса. Перегруженную функцию оператора << (>>) можно объявить в качестве дружественной функции класса, таким образом он сможет получить доступ к конфиденциальным данным в объекте. Перегруженный оператор возвращает ссылку на исходный объект ostream (istream), что позволяет объединять вставки (cout << a << endl << b;).
class example
{
private:
int a;
public:
example() {}
example(int a) { this->a = a; }
~example() {}
friend ostream& operator << (ostream&, const example &);
};
ostream& operator << (ostream& os, const example &E)
{
os << E.a <<endl;
return os;
}
20. Перегрузка оператора [] (в том числе и для многомерных массивов)
тип& operator [] (int);
Применяется для индексирования массивов. По смыслу тип принимаемого параметра – int. Возвращаемый тип – ссылка на элемент массива, для использования в левой части в выражениях с присваиваниями.
При перегрузке оператора [] для многомерных массивов следует помнить, что данный оператор заменяет только первый оператор []. Поэтому в качестве возвращаемого типа должен быть указатель из первого слоя указателей в данной структуре.
Для одномерного массива:
class example
{
private:
int size;
int* a;
public:
example()
{
size = 1;
a = new int[1];
}
example(int r)
{
size = r;
a = new int[r];
for(int i = 0; i < r; i++)
a[i] = i;
}
~example()
{
delete [] a;
}
int operator [] (int index)
{
if( index < 0 || index > size)
return a[0];
return a[index];
}
};
Для многомерного массива:
class example
{
private:
int m;
int n;
int** b;
public:
example()
{
m = 1;
n = 1;
b = new int* [1];
b[0] = new int[1];
}
example(int M, int N)
{
m = M;
n = N;
b = new int* [m];
for(int i = 0; i < m; i++)
{
b[i] = new int[n];
for(int j = 0; j < n; j++)
b[i][j] = 10*i + j;
}
}
~example()
{
for(int i = 0; i < m ; i++)
delete [] b[i];
delete [] b;
}
int* operator [] (int index)
{
if( index < 0 || index > m)
return b[0];
return b[index];
}
};
Дата добавления: 2022-02-05; просмотров: 271;