Перегрузка операторов
Классы в языке С++ предоставляют возможность переопределять работу некоторых операторов таких как «=», «+», «*», «new», «delete», «==», «>», «<» и др. Это дает возможность упрощать текст программы и повышать качество программирования. Преимущества от перегрузки операторов удобно продемонстрировать при работе со строками, которые в базовом языке С++ представляют собой массивы символов и операции присваивания, добавления и сравнения строк становятся сложными. Зададим класс TString, в котором будут описаны алгоритмы обработки строковой информации.
В данном классе описано два конструктора для возможности создания пустой и некоторой начальной строк. Кроме того, задано два метода: Get() и Set(), через которые осуществляется доступ к массиву buff[], являющимся частным свойством класса.
Перегрузка оператора выполняется с помощью ключевого слова operator, за которым следует символ оператора, затем в круглых скобках аргументы. Пример перегрузки оператора «=» для присваивания строки показан на листинге выше. Обратите внимание, что перед оператором ставится возвращаемый им тип, в данном случае void. После перегрузки оператора присваивания с классом TString становятся возможны следующие действия:
Здесь при выполнении операции присваивания активизируется алгоритм, записанный в теле оператора «=», а именно функция strcpy(), в которой указатель str указывает на строку символов, стоящих справа от оператора присваивания. Особенностью перегрузки данного оператора является то, что он будет работать только в том случае, когда его правый аргумент является массивом символов, и не будет выполняться в случае присваивания одного класса TString другому:
Вместе с тем такая запись вполне логична и естественна и желательно чтобы ее можно было использовать. Это достигается путем добавления в класс TString еще одной реализации перегрузки оператора присваивания, следующим образом:
В итоге, при реализации строки
будет вызываться второй вариант перегрузки оператора присваивания. Причем компилятор сам определит, какой из вариантов перегрузки вызывать в каждом конкретном случае. В представленном примере перегрузки аргументом является ссылка на класс TString, а не представитель этого класса. Это сделано, для того чтобы при реализации оператора присваивания не происходило копирование класса TString при передаче аргумента и (см. § 4.1), таким образом, экономилась память ЭВМ и увеличивалась скорость работы. Следующим шагом оптимизации работы со строками выполним перегрузку оператора добавления одной строки другой, которая будет определяться символом «+». Желательно использовать для вызова оператора «+» запись вида
Но здесь используется сразу два оператора: присваивания и добавления. Поэтому для реализации такой конструкции необходимо, чтобы оператор добавления «+» возвращал сформирванную строку оператору присваивания. Следовательно, описание оператора добавления в классе TString должно выглядеть так:
Наконец, последним шагом выполним перегрузку условного оператора сравнения двух строк между собой. Реализация этого оператора очевидна и выглядит следующим образом:
В результате получаем следующее описание класса TString:
который можно использовать следующим образом:
Лабораторная работа № 12. Наследование Продолжительность – 4 часа. Максимальный рейтинг – 8 баллов. Цель работы Научиться создавать классы-потомки на основе базовых классов и описывать их свойства и методы. Научиться применять конструкторы базового класса в соответствующих конструкторах наследуемых классов. Освоить умение работать с абстрактыми классами, дружественными и виртуальными функциями и научиться перегружать операторы. Закрепить навыки конструирования классов, выделения памяти под динамические объекты класса, освобождения памяти, обращения к их свойствам и методам. Задание на лабораторную работу 1. Задать базовый класс и классы-потомки на его основе, реализующие операции с данными, в соответствии с индивидуальным заданием (Таблица 15). Если возможно, реализовать множественное наследование. 2. В базовом классе обязательно создать конструктор_по_умолчанию и конструктор_с_параметрами, а также деструктор класса. Продемонстрировать применение в конструкторах классов-потомков соответствующих конструкторов базового класса. 3. Сделать базовый класс абстрактным. Продемонстрировать вызов методов абстрактного класса через объекты класса-потомка. 4. Продемонстрировать использование дружественной функции. 5. Продемонстрировать реализацию виртуальной функции в базовом классе и в классах-потомках. 6. Продемонстрировать перегрузку хотя бы одного оператора. 7. В отчете привести листинг программы, скриншоты тестирования программы, рисунок структуры класса. Листинг программы без комментариев не принимается.
Варианты индивидуальных заданий Внимание! Варианты индивидуальных заданий составлены таким образом, чтобы продолжать выполнение индивидуального задания из предыдущей лабораторной работы (Лабораторная работа № 11. Классы). Рекомендуется выполнять тот же вариант индивидуального задания, что и в предыдущей работе (Таблица 14). Таблица 15 Варианты индивидуальных заданий
Шаблоны
- Вот представь: у тебя есть 1000 рублей... Или нет, для круглого счета, пусть у тебя 1024 рубля... Шаблоны функций Шаблоны – это средство языка C++, предназначенное для кодирования обобщённых алгоритмов, без привязки к некоторым параметрам (например, типам данных, размерам буферов, значениям по умолчанию). В C++ возможно создание шаблонов функций и классов.
Шаблоны начинаются со слова template, после которого идут угловые скобки, в которых перечисляется список параметров. Каждому параметру должно предшествовать зарезервированное слово class или typename.
Ключевое слово typename говорит о том, что в шаблоне будет использоваться встроенный тип данных, такой как: int, double, float, char и т. д. А ключевое слово class сообщает компилятору, что в шаблоне функции в качестве параметра будут использоваться пользовательские типы данных. Например, нам нужно запрограммировать функцию, которая выводила бы на экран элементы массива. Задача не сложная, но, чтобы написать такую функцию, мы должны задать тип данных массива, который будем выводить на экран. А если требуется, чтобы функция выводила массивы различных типов – int, double, float и char? Можно воспользоваться перегрузкой функций (см. § 4.2), но придется написать целых 4 функции, которые отличаются только заголовком функции, тело у них абсолютно одинаковое! Для этого в С++ и придуманы шаблоны функций. Мы создаем один шаблон, в котором описываем все типы данных. А какой тип данных использовать в конкретной реализации, будет определено позже при компиляции функции.
В листинге перед объявлением функции стоит запись template <typename T>. Как раз эта запись и говорит о том, что функция print_array() на самом деле является шаблоном функции, так как в первом параметре print_array() стоит тип данных const T*. Это определение шаблона с одним параметром – T, причем этот параметр будет иметь один из встроенных типов данных, так как указано ключевое слово typename. По сути T – это даже не тип данных, это зарезервированное место под любой встроенный тип данных. То есть когда выполняется вызов этой функции, компилятор анализирует параметр шаблонированной функции и создает экземпляр для соответственного типа данных: int, char и так далее.
Шаблоны классов будут рассмотрены ниже в применении к динамическим структурам.
Воспользуйтесь поиском по сайту: ©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...
|