6.5. Перегрузка операторовКлассы в языке С++ предоставляют возможность переопределять работу некоторых операторов таких как ‘=’, ‘+’, ‘*’, ’new’, ‘delete’, ‘==’, ‘>’, ‘<э’ и др. Это дает возможность упрощать текст программы и повышать качество программирования. Преимущества от перегрузки операторов хорошо проявляются при работе со строками, которые в базовом языке С++ представляют собой массивы символов и операции присваивания, добавления и сравнения строк становятся сложными. Однако, используя классы можно сделать работу со строками подобно работе с обычными переменными. Зададим класс string, в котором будут описаны алгоритмы обработки строковой информации:
В данном классе описано два конструктора для возможности создания пустой и некоторой начальной строк. Кроме того, задано два метода: GetString() и SetString(), через которые осуществляется доступ к массиву buff[], являющимся частным элементом класса. Представленный класс описывает минимальный набор функций для работы со строками. С помощью него можно лишь задать какую-либо строку и получить ее, например, для вывода на экран. Все возможные манипуляции со строками с помощью класса string демонстрирует текст программы, представленный ниже:
При этом операции присваивания одной строки другой, добавления, сравнения строк между собой и т.п. остаются нереализованными. Формально для выполнения этих операций можно задать набор функций в классе string, но ими будет менее удобно пользоваться, чем общеизвестными операторами ‘=’, ‘+’и ‘==’. Для того чтобы сказать, что должен делать конкретный оператор при работе с классом string, его нужно перегрузить, т.е. определить алгоритм, который будет выполняться при реализации того или иного оператора. Перегрузка оператора выполняется с помощью ключевого слова operator, за которым следует символ оператора, затем в круглых скобках аргумент, т.е. то, что предполагается будет стоять справа от оператора. После этого в бигурных скобках задается алгоритм, который будет выполняться при вызове перегруженного оператора. Пример перегрузки оператора ‘=’ для присваивания строки показан ниже:
Обратите внимание, что перед оператором ставится возвращаемый им тип, в данном случае void. Возвращаемый тип необходим при реализации, например, условных операторов, о которых речь пойдет ниже. После перегрузки оператора присваивания с классом string становятся возможны следующие действия:
Здесь при выполнении операции присваивания активизируется алгоритм, записанный в теле оператора, а именно функция strcpy(), в которой указатель str указывает на строку символов, стоящих справа от оператора присваивания. Таким образом, происходит копирование переданной строки в массив buff класса string. Следует также отметить, что описанное действие оператора присваивания распространяется только на класс string. Это значит, что при выполнении, например, операций над числами:
оператор присваивания будет работать корректно, обычным образом. Особенностью перегрузки данного оператора является то, что он будет работать только в том случае, когда его правый аргумент является массивом символов и не будет выполняться в случае присваивания одного класса string другому:
Вместе с тем такая запись вполне логична и естественна и желательно чтобы ее можно было использовать наряду с простыми массивами. Это достигается путем добавления в класс string еще одной реализации перегрузки оператора присваивания, следующим образом:
В итоге, при реализации алгоритма
будет вызываться второй вариант перегрузки оператора присваивания. Причем компилятор сам определит, какой из вариантов перегрузки вызывать в каждом конкретном случае. В представленном примере перегрузки аргументом является ссылка на класс string, а не представитель этого класса. Это сделано, для того чтобы при реализации оператора присваивания не происходило копирование класса string при передаче аргумента и, таким образом, экономилась память ЭВМ и увеличивалась скорость работы. Поэтому, формально, программа будет работать, если вместо ссылки использовать представитель класса. Следующим шагом оптимизации работы со строками выполним перегрузку оператора добавления одной строки другой, которая будет определяться символом ‘+’. Для этого, по аналогии, добавим в класс string следующие строки:
который возможно использовать только таким образом:
Это несколько непривычная запись оператора добавления строки. Было бы правильнее использовать запись вида
но здесь используется сразу два оператора: присваивания и добавления. Поэтому для реализации такой конструкции необходимо, чтобы оператор добавления ‘+’ возвращал сформирванную строку оператору присваивания. Следовательно, описание оператора добавления в классе string должно выглядеть так:
Наконец, последним шагом выполним перегрузку условного оператора сравнения двух строк между собой. Реализация этого оператора очевидна и выглядит следующим образом:
В результате получаем следующее описание класса string:
который можно использовать следующим образом:
Видео по теме
С++ с нуля: урок 1 - переменные, оператор присваивания С++ с нуля: урок 2 - арифметические операции С++ с нуля: урок 3 - директивы препроцессора С++ с нуля, урок 4: условные операторы if и switch С++ с нуля: урок 5 - операторы циклов while, for и do while С++ с нуля: урок 6 - массивы, метод всплывающего пузырька С++ с нуля: урок 7 - строки и функции работы с ними С++ с нуля: урок 8 - функции: прототипы, перегрузка, рекурсия С++ с нуля: урок 9 - области видимости переменных С++ с нуля: урок 10 - битовые операции И, ИЛИ, НЕ, XOR С++ с нуля: урок 11 - структуры С++ с нуля: урок 12 - объединения, перечисления, typedef С++ с нуля: урок 13 - указатели и ссылки, выделение памяти С++ с нуля: урок 14 (часть 1) - функции работы с файлами С++ с нуля: урок 14 (часть 2) - функции работы с файлами С++ с нуля: урок 15 - стек, теория и практика С++ с нуля: урок 16 - связные списки, теория и практика С++ с нуля: урок 17 - бинарное дерево, теория и практика
|