Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
OOP_otvety_k_ekzamenu.doc
Скачиваний:
55
Добавлен:
13.04.2015
Размер:
786.94 Кб
Скачать

14. Перегрузка операторов сравнения и арифметических операторов. Основные правила реализации и применения.

● Глобальный оператор ==:

// Реализация глобального оператора сравнения на равенство дат

inline bool operator == ( const Date & d1, const Date & d2 )

{ return d1.GetYear() == d2.GetYear() &&

d1.GetMonth() == d2.GetMonth() &&

d1.GetDay() == d2.GetDay() ;}

Если перегружен оператор сравнения на равенство (==), логично перегрузить и противоположный по смыслу оператор сравнения на неравенство (!=). Обычно проверку на неравенство реализовывают не по аналогии с проверкой на равенство, а как отрицание результата перегруженного оператора равенства. Это позволяет изменять семантику операции сравнения на равенство в единственном месте в коде, получая обновленный оператор сравнения на неравенство без малейших усилий.

● Глобальный оператор != :

// Уже имеющийся глобальный оператор сравнения на равенство дат

inline bool operator == ( const Date & d1, const Date & d2 );

// Реализация нового глобального оператора сравнения на неравенство дат

inline bool operator != ( const Date & d1, const Date & d2 )

{ // Неравенство - это отрицание равенства

return !( d1 == d2 ); }

В приведенном ниже примере перегружаются остальные операторы сравнения ( <, <=, >, >= ). При этом, фактически полностью определяется только один их операторов - сравнение по “меньше” (<), а остальные выражаются через него и ранее определенный оператор сравнения на равенство (==). Все операторы сравнения объединяет возвращаемый логический тип.

class Date

{ // … без изменений …

public:

// Объявление еще 4 перегруженных операторов сравнения

bool operator < ( const Date & d ) const;

bool operator <= ( const Date & d ) const;

bool operator > ( const Date & d ) const;

bool operator >= ( const Date & d ) const;

};

// Реализация оператора сравнения по “меньше”

bool Date::operator < ( const Date & d ) const

{ // Если год нашей даты меньше года той даты, то наша дата меньше той

if ( m_Year < d.GetYear() )

return true;

// Если год нашей даты равен году той даты - сравниваем месяцы

else if ( m_Year == d.GetYear() )

{ // Аналогично, при равных годах, если месяц нашей даты меньше месяца той даты,то наша дата меньше той

if ( m_Month < _d.GetMonth() )

return true;

// Если и годы, и месяцы равны, то следует сравнить дни

else if ( m_Month == _d.GetMonth() )

return m_Day < _d.GetDay();

// Если при равных годах месяц нашей даты больше месяца той даты,

// то наша дата больше той ( выйдем по return false ниже )

}

// Если год нашей даты больше года той даты, наша дата больше той

return false;

}

// Реализация оператора сравнения по “больше”:

// достаточно поменять местами операнды и сравнить даты по “меньше”

bool Date::operator > ( const Date & d ) const

{ return d < * this;}

// Реализация оператора сравнения по “меньше или равно”:

// истина => когда наша дата либо меньше той даты, либо равна ей

// ложь => в остальных случаях ( когда сработает > )

bool Date::operator <= ( const Date & d ) const

{ return ( * this < d ) || ( * this == d );}

// Реализация оператора сравнения по “больше или равно”:

// истина => когда та дата меньше нашей даті, ли равна ей

// ложь => в остальных случаях ( когда сработает < )

bool Date::operator >= ( const Date & d ) const

{ return ( d < * this ) || ( * this == d );}

Перегрузка оператора сравнения по “меньше” имеет широкое применение. Например, это является необходимым условием, чтобы массивы объектов классов можно было сортировать без применения специальных объектов-компараторов, как массивы встроенных типов. Оператор “<” также пригодится для реализации бинарного дерева поиска (BST).

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

Обычно, арифметические операторы перегружаются связанными парами:

● немодифицирующий оператор, принимающий два объекта-операнда, возвращающий новый результат (новый объект или число, в зависимости от смысла оператора)

● модифицирующий оператор, принимающий два объекта и формирующий итоговый результат в первом объекте (возвращает ссылку на себя).

Например, если перегружается оператор немодифицирующий сложения “+”, то перегружают и парный ему модифицирующий оператор “+=” и т.д. Обычно определяют реализацию для одного из них в виде какого-либо алгоритма, а парный оператор реализовывают на основе вызова первого. Какой именно из операторов пары брать за основу не имеет принципиального значения.

В случае необходимости оператор может быть перегружен в нескольких версиях, если типы аргументов отличаются между собой. Это реализуется при помощи механизма перегрузки функций. В данном случае в С++ имеется терминологический конфликт - перегрузка перегруженных операторов (overloading overloaded operators). Первое слово “перегрузка” означает наличие функций, обладающих одинаковым названием, но различными типами/количеством аргументов. Второй слово “перегруженных” означает обсуждаемую в данной лекции перегрузку операторов.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]