Skip to content

Перегрузка операторов

Pandas edited this page Jun 16, 2017 · 2 revisions

При задаче «нового» оператора необходимо учесть несколько аспектов.

  • Приоритет (* раньше +);
  • арность (со сколькими операндами работаем);
  • порядок выполнения (слеванаправо или справаналево).

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

Запрещены к перегрузке: . :: . (вызов метода через указатель в СИ) ?: (тернарный).*

[тип] operator<знак> ([список параметров]) //longint operator * (longint &a, longint &b)

⚫️ Операторы можно перегружать как члены или как внешные функции (дружественные или нет). ⚫️ Оператор нью перегружается как статический метод класса (он вызывается чтобы создать объект – когда самого объекта нет).

Существует три формы его перегрузки.

//объявляется методом класса
void* operator new(size_t Size[,  void *buff]); //модификатор статик можно написать, но здесь он используется автоматически
void* operator new[](size_t C); //нью служит ТОЛЬКО для выделения памяти; после возвращения области начинает работать конструктор
//delete возвращает void а не указатель
A* obj = new A;

Вернёмся к бинарным операторам + - * /. Принято: если бинарный оператор изменяет существующие объекты, перегружать его надо как член класса, к примеру A+B == A += B.

Complex operator +(const Complex& C1, const Complex& C2)
{
	return complex(C1.rl+C2.rl, C1.im+C2.im);
}

Оператор при этом должен быть другом класса.

Присваивание перегружается как член класса; выполняется справа налево. Перегрузка присваивания не влияет на инициализацию.

() перегружаются как оператор-член класса, НЕ статический. Получит как минимум один параметр – this, адрес объекта для которого был вызван. () нельзя перегружать для одного класса несколько раз – только единожды.

[] индексация. Позволяет создавать ассоциативные массивы. После перегрузки теряется транзитивность – вызываться будет всегда для левого объекта.

// ->
class A
{
public:
	void f();
};

class B
{
public:
	A* operator->();
};

B obj;
obj->f(); //(obj.operator->())->f()

Так называемый «умный указатель» - можно создавать объекты, выполняющие чисто транзитные операции. Через них вызываются методы нужного объекта. Позволяет работать со всеми объектами класса А, включая и производные, и даже если А абстрактный (virtual void f()=0;)

++ -- инкремент и декремент. Постфиксный вариант выполняется после того, как объект отработал в выражении; учесть это никак нельзя.

class A
{
public:
	A& operator++(); //++a
	A& operator++(int); //a++0
	operator int(); //оператор неявного приведения типа
}
Clone this wiki locally