Доступ к готовым решениям

Переход в группу "Пользователь"

300.00 ₽
Одноразовый платёж
Быстрый переход в группу "Пользователи", без надобности написания постов и ожидания.

Покупка дает возможность:
Быть полноправным участником форума
Нормальное копирование кода
Создавать темы
Скачивать файлы
Доступ к архиву Pawno-Info

Урок [Цикл уроков программиста] 15. Перегрузка операции

Статус
В этой теме нельзя размещать новые ответы.

A_Trigger

Умник
Сегодня мы познакомимся с замечательной возможностью нашего любомого языка C++ - перегрузкой операций. Но сначала разберёмся, для чего это нужно.

С базовыми типами вы можете использовать любые операции: +, -, *, ++, = и многие другие. Например:

PHP:
int a=2,b=3,c;
c = a + b;
Здесь над переменными типа int сначала выполняется операция +, а затем результат присваивается переменной c с помощью операции =. Над классами такое проделать не получится. Создадим простой класс:
PHP:
class Counter
{
public:
  int count;
  Counter() : count(0) {}
};

Counter a,b,c;
a.count = 2;
b.count = 3;
c = a + b;
Здесь компилятор выдаст ошибку на последней строке: он не знает как именно нужно действовать при использовании операций = и + над объектами класса Counter. Можно решить данную проблему вот так:

PHP:
class Counter
{
public:
  int count;
  Counter() : count(0) {}
  void AddCounters (Counter& a, Counter& b)
  {
    counter = a.count + b.count;
  }
};

Counter a,b,c;
a.counter = 2;
b.counter = 3;
c.AddCounters(a,b);

Согласитесь, использование операции + и = в данном случае сделало бы программу более понятной. Так вот, чтобы использовать стандартные операции C++ с классами, эти операции нужно перегрузить (overload).
Перегрузка унарных операций

Начнём с простых операций - унарных. Прежде всего нас интересует инкремент. При использовании данной операции над базовыми типами, к переменной можно прибавить или отнять единицу:
PHP:
int a=1;
++a; // a = 2;
--a; // a = 1;
Теперь научим класс Counter использовать преинкремент (предекремент):
PHP:
class Counter
{
private:
  count;

public:
  Counter() : count(0) {}
  void operator++ ()
  {
    count += 1; // Можно также count++ или ++count -
                  // это не имеет значения в данном случае.
  }
};

Counter a;
++a;
++a;
++a;
Этот код работает. При использовании операции ++ (важно чтобы этот знак находился до идентификатора!) над объектом класса Counter, происходит увеличение переменной counter объекта a.

В данном примере мы перегрузили операцию ++. Делается это созданием метода внутри класса. Единственной важной особенностью данного метода - имя идентификатора. Имя идентификатора для перегруженных операций состоит из ключевого слова operator и названия операции. Во всём остальном этот метод определяется как и любые другие.

Использовать перегруженные операции с пользовательскими типами очень просто - так же как и с обычными типами данных.
Перегрузка постфиксных операций

Примеры постфиксной операции:
PHP:
int a = 3;
a++;
a--;

То есть, здесь знак операции ставится после имени идентификатора. Для использования постфиксных операций с пользовательскими типами данных нужно совсем немного:
PHP:
public:
  void operator++ ()
  {
    counter += 1;
  }
  void operator++ (int)
  {
    counter += 1;
  }
Единственным отличием префиксной операции от постфиксной - ключевое слово int в списке аргументов. Но int - это не аргумент! Это слово говорит, что перегружается постфиксная операция. Теперь операцию ++ можно использовать как перед идентификатором объекта, так и после:
PHP:
Counter a;
++a;
++a;
a++;
a++;
Перегрузка бинарных операций

Перегрузка операций с двумя аргументами очень похожа на перегрузку бинарных операций:
PHP:
Counter operator+ (Counter t)
{
  Counter summ;
  summ.counter = counter + t.counter;
  return summ;
}

Counter c1,c2,c3;
c1.counter = 3;
c2.counter = 2;

c3 = c1 + c2;
Какая переменная вызовет функцию operator+? В перегруженных бинарных операциях всегда вызывается метод левого операнда. В данном случае метод operator+ вызывает объект c1.

В метод мы передаём аргумент. Аргументом всегда является правый операнд.

Кроме того, в данном случае операция + должна вернуть какой-то результат, чтобы присвоить его объекту c3. Мы возвращаем объект Counter. Возвращаемое значение присваивается переменной c3.

Заметьте, мы перегрузили операцию +, но не перегружали операцию =! Конечно же нужно добавить этот метод к классу Counter:
PHP:
Counter operator= (Counter t)
{
  Counter assign;
  counter = t.counter;
  assign.counter = t.counter;
  return assign;
}

Внутри метода мы создали дополнительную переменную assign. Данная переменная используется, чтобы можно было работать вот с таким кодом:

PHP:
Counter c1(5),c2,c3;
c3 = c2 = c1;

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