Выбрать главу

.    ::    .*    ?

Оператор ".*" — это оператор специального назначения (он рассматривается ниже в этой книге).

О значении порядка операндов

Перегружая бинарные операторы, помните, что во многих случаях порядок следования операндов имеет значение. Например, выражение А+В коммутативно, а выражение А-В — нет. (Другими словами, А - В не то же самое, что В - А!) Следовательно, реализуя перегруженные версии некоммутативных операторов, необходимо помнить, какой операнд стоит слева от символа операции, а какой — справа от него. Например, в следующем фрагменте кода демонстрируется перегрузка оператора вычитания для класса three_d.

// Перегрузка оператора вычитания.

three_d three_d::operator-(three_d op2)

{

 three_d temp;

 temp.x = x - op2.x;

 temp.у = у - op2.y;

 temp.z = z - op2.z;

 return temp;

}

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

х - ор2.х.

Перегрузка операторов с использованием функций-не членов класса

Бинарные операторные функции, которые не являются членами класса, имеют два параметра, а унарные (тоже не члены) — один.

Перегрузку оператора для класса можно реализовать и с использованием функции, не являющейся членом этого класса. Такие функции часто определяются "друзьями" класса. Как упоминалось выше, функции-не члены (в том числе и функции-"друзья") не имеют указателя this. Следовательно, если для перегрузки бинарного оператора используется функция-"друг", явным образом передаются оба операнда. Если же с помощью функции-"друга" перегружается унарный оператор, операторной функции передается один оператор. С использованием функций-не членов класса нельзя перегружать такие операторы:

=, (), [] и ->.

Например, в следующей программе для перегрузки оператора "+" вместо функции-члена используется функция-"друг".

// Перегрузка оператора "+" с помощью функции-"друга".

#include <iostream>

using namespace std;

class three_d {

  int x, y, z; // 3-мерные координаты

 public:

  three_d() { x = у = z = 0; }

  three_d(int i, int j, int k) { x = i; у = j; z = k; }

  friend three_d operator+(three_d op1, three_d op2);

  three_d operator= (three_d op2); // Операнд op1 передается неявно.

  void show();

};

// Теперь это функция-"друг".

three_d operator+(three_d op1, three_d op2)

{

 three_d temp;

 temp.x = op1.x + op2.x;

 temp.у = op1.у + op2.y;

 temp.z = op1.z + op2.z;

 return temp;

}

// Перегрузка присваивания.

three_d three_d::operator=(three_d op2)

{

 x = op2.x;

 у = op2.у;

 z = op2.z;

 return *this;

}

// Отображение координат X, Y, Z.

void three_d::show()

{

 cout << x << ", ";

 cout << у << ", ";

 cout << z << "\n";

}

int main()

{

 three_d a(1, 2, 3), b(10, 10, 10), c;

 a.show();

 b.show();

 с = a + b; // сложение объектов а и b

 c.show();

 c=a+b+c; // сложение объектов a, b и с

 с.show();