Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка - Основи Програмування C_.doc
Скачиваний:
46
Добавлен:
18.12.2018
Размер:
1.44 Mб
Скачать

3. Перевантаження унарних операцій.

У множині геометричних векторів існує також поняття протилежного вектору – це вектор з координатами, що мають протилежні знаки. Крім того, хоча подібної операції у математиці не визначено, реалізуємо операції інкременту та декременту для векторів. Результуючий вектор матиме координати на одиницю більші або відповідно менші за координати заданого вектору. Це унарні операції, тобто пов’язані лише з одним операндом. Їх результатом також має бути вектор. При цьому операція унарний мінус не повинна змінювати початковий вектор на відміну від операцій інкременту та декременту. Це необхідно врахувати у коді операторних методів. Зауважимо також, що для перевантажених операцій ++ та неможливо реалізувати постфіксний та префіксний варіанти цих операцій – прийдеться задовольнитись тим, що обидві форми інкременту та декременту працюють однаковим чином. Включимо у клас відповідні операторні функції:

public static d2Vector operator -(d2Vector v) // унарний мінус

{

d2Vector temp = new d2Vector(-v.x, -v.y);

return temp;

}

public static d2Vector operator ++(d2Vector v) // інкремент

{

v.x += 1; v.y += 1;

return v;

}

public static d2Vector operator --(d2Vector v) // декремент

{

v.x -= 1; v.y -= 1;

return v;

}

Внесемо також у метод Main() код для тестування новостворених методів:

b = -a;

Console.WriteLine("b = -a: " + b.ToString());

a++;

Console.WriteLine("a++: " + a.ToString());

a--;

Console.WriteLine("a--: " + a.ToString());

// префіксна та постфіксна форми працюють однаково

++a;

Console.WriteLine("++a: " + a.ToString());

--a;

Console.WriteLine("--a: " + a.ToString());

Результати цих дій будуть наступними:

b = -a: x = -1 y = -2

a++: x = 2 y = 3

a--: x = 1 y = 2

++a: x = 2 y = 3

--a: x = 1 y = 2

4. Перевантаження операцій відношення.

Як відомо, вектори можна перевіряти на рівність та нерівність між собою – це означає порівняння їх координат. Отже, маємо перевантажити і операції == та !=. До речі, стосовно операцій відношення діє правило: якщо ви перевантажуєте одну з операцій == та !=, то обов’язково маєте перевантажити і іншу. Те саме стосується і пар операцій < і > та <= і >=. Результатом відповідних операторних методів обов’язково має бути true або false. Створимо операторні методи для перевантаження операції == та != у класі d2Vector.

// перевірка векторів на рівність

public static bool operator ==(d2Vector v1, d2Vector v2)

{ return ((v1.x == v2.x) && (v1.y == v2.y)); }

// перевірка векторів на нерівність

public static bool operator !=(d2Vector v1, d2Vector v2)

{ return ((v1.x != v2.x) || (v1.y != v2.y)); }

Програма з цими методами буде скомпільована та готова до виконання, проте ми одержимо зауваження від компілятора, щодо того, що при перевантаженні операцій == та != не заміщаються методи Object.Equals() та Object.GetHashCode(). Справа в тому, що метод Object.Equals() перевіряє рівність двох посилальних типів і успадкований будь-яким класом від класу Object. Проте у разі перевантаження операцій перевірки рівності та нерівності об’єктів, компілятор хоче мати певність, що перевантажена операція == та метод Equals() використовують однакову логіку порівняння. Саме тому компілятор і радить заміщення цього методу. Що стосується методу GetHashCode(), то він потрібний, якщо екземпляри класу можуть використовуватись в ролі ключів у hash-таблицях. Оскільки векторам така роль не загрожує, просто проігноруємо це зауваження компілятора, а от метод Equals() мусимо таки замістити. Проте потім ми використаємо його в операторних методах == та !=. Отже, замість запропонованого вище фрагменту коду включимо наступний:

public override bool Equals(Object obj) // заміщений метод із System.Object

{ // його перевантаження вимагає operator == та operator !=

if (obj == null || GetType() != obj.GetType())

return false;

d2Vector v = (d2Vector)obj;

return ((x == v.x) && (y == v.y));

}

// перевірка векторів на рівність

public static bool operator ==(d2Vector v1, d2Vector v2)

{

return v1.Equals(v2);

}

// перевірка векторів на нерівність

public static bool operator !=(d2Vector v1, d2Vector v2)

{

return ((v1.x != v2.x) || (v1.y != v2.y));

}

Напишемо також код для тестування цих методів у Main():

Console.WriteLine((a == b));

Console.WriteLine((a != b));

Після запуску одержимо наступні повідомлення:

false

true