x = 1
y = 1
Проекции вектора AC x = 1 y = 1.73205
Координаты точки C x = 2 y = 2.73205
В приведённом примере решена следующая задача. Заданы две вершины равностороннего треугольника. Нужно вычислить третью вершину. Приведено одно из двух возможных математических решений.
Не следует путать выражения, использующие круглые скобки: Vec AC ("AC") с AC (AB, 60). Первое вызывает конструктор с параметрами, второе – перегруженный оператор вызова функции.
Функции преобразования типа
Часто встречается задача преобразования объекта одного типа в объект другого типа. Мы уже рассмотрели ранее возможность такого преобразования с помощью конструкторов. Однако конструкторы преобразования имеют одно существенное ограничение: они позволяют преобразовать встроенный тип данных в объект, но не наоборот. Функции преобразования типа предоставляют возможность обратного преобразования объекта некоторого класса к любому из встроенных типов. Они имеют следующий вид:
operator <имя_нового_типа> ();
Функции преобразования подчиняются следующим правилам:
ü функция преобразования не имеет параметров;
ü в функциях преобразования типа не задается тип возвращаемого значения;
ü функция преобразования типа возвращает тип, указанный после ключевого слова operator;
ü функция преобразования типа может быть вызвана неявно;
ü функция преобразования типа наследуется.
В следующем примере функции преобразования вектора в число используется для вычисления длины вектора:
Файл Vec.h
class Vec // класс вектора
{
• • •
public:
Vec operator * (double m); // перегрузка оператора умножения вектора на число
Vec operator / (double d); // перегрузка оператора деления вектора на число
operator double (); // функция преобразования вектора в число
};
Файл Vec.cpp
#include "Vec.h"
• • •
Vec Vec:: operator * (double m) // перегрузка оператора умножения вектора на число
{
Vec T ("T", x * m, y * m); // объявляет и инициализирует временный объект
return T; // возвращает временный объект
}
Vec Vec::operator / (double d) // перегрузка оператора умножения вектора на число
{
Vec T ("T", x / d, y / d); // объявляет и инициализирует временный объект
return T; // возвращает временный объект
}
Vec::operator double () // функция преобразования вектора в число
{
return sqrt (x*x + y*y); // возвращает длину текущего вектора
}
Файл Main.cpp
#include "Vec.h"
Void main ()
{
char S [ ] = "Длина вектора ";
CharToOem (S, S);
Vec V ("V", 1, 1),W ("W"), N ("N"); // объявляет вектора
~ (N = V / V); // неявный вызов функции преобразования вектора в число,
// вычисляет нормированный вектор,
// выводит на экран проекции нормированного вектора.
cout << S << "N =\t" << (double) N << '\n'; // явный вызов функции преобразования вектора в число
~ (W = N * 2.0); // вычисляет вектор W, длина которого равна 2,
// выводит на экран проекции вектора W.
cout << S << "W =\t" << (double) W << '\n';
}
В приведённом примере решена задача вычисления вектора заданной длины. Для этого мы сначала нормируем вектор – делим вектор на его длину, а затем умножаем на заданное число. Функция преобразования вектора в число в нашей программе используется в двух разных формах.
Выражение cout << (double) N << '\n' содержит явный вызов функции преобразования вектора в число и используется для вывода на экран длины вектора.
Выражение ~ (N = V / V) содержит операцию деления вектора на вектор, которая нами не определена. Поэтому компилятор ищет самый “подходящий” перегруженный оператор. Таким оператором в классе Vec оказывается перегруженный оператор деления вектора на число. Поскольку в классе Vec определена функция преобразования вектора в число, которая может быть вызвана неявно, то у компилятора появляется возможность однозначно трактовать выражение V / V как V / (double) V.
При выполнении программа выводит на экран:
Проекции вектора N x = 0.707107 y = 0.707107
Длина вектора N = 1
Проекции вектора W x = 1.41421 y = 1.41421
Длина вектора W = 2