9.1.3. Когда не надо перегружать имя функции
9.1.3. Когда не надо перегружать имя функции
В каких случаях перегрузка имени не дает преимуществ? Например, тогда, когда присвоение функциям разных имен облегчает чтение программы. Вот несколько примеров. Следующие функции оперируют одним и тем же абстрактным типом даты. На первый взгляд, они являются подходящими кандидатами для перегрузки:
void setDate( Date, int, int, int );
Date convertDate( const string );
void printDate( const Date );
Эти функции работают с одним типом данных – классом Date, но выполняют семантически различные действия. В этом случае лексическая сложность, связанная с употреблением различных имен, проистекает из принятого программистом соглашения об обеспечении набора операций над типом данных и именования функций в соответствии с семантикой этих операций. Правда, механизм классов C++ делает такое соглашение излишним. Следовало бы сделать такие функции членами класса Date, но при этом оставить разные имена, отражающие смысл операции:
#include string
class Date {
public:
set( int, int, int );
Date convert( const string );
void print();
// ...
};
Приведем еще один пример. Следующие пять функций-членов Screen выполняют различные операции над экранным курсором, являющимся принадлежностью того же класса. Может показаться, что разумно перегрузить эти функции под общим названием move():
Screen moveHome();
Screen moveAbs( int, int );
Screen moveRel( int, int, char *direction );
Screen moveX( int );
Screen moveY( int );
Впрочем, последние две функции перегрузить нельзя, так как у них одинаковые списки параметров. Чтобы сделать сигнатуру уникальной, объединим их в одну функцию:
// функция, объединяющая moveX() и moveY()
Screen move( int, char xy );
Теперь у всех функций разные списки параметров, так что их можно перегрузить под именем move(). Однако этого делать не следует: разные имена несут информацию, без которой программу будет труднее понять. Так, выполняемые данными функциями операции перемещения курсора различны. Например, moveHome() осуществляет специальный вид перемещения в левый верхний угол экрана. Какой из двух приведенных ниже вызовов более понятен пользователю и легче запоминается?
// какой вызов понятнее?
myScreen.home(); // мы считаем, что этот!
myScreen.move();
В некоторых случаях не нужно ни перегружать имя функции, ни назначать разные имена: применение подразумеваемых по умолчанию значений аргументов позволяет объединить несколько функций в одну. Например, функции управления курсором
moveAbs(int, int);
moveAbs(int, int, char*);
различаются наличием третьего параметра типа char*. Если их реализации похожи и для третьего аргумента можно найти разумное значение по умолчанию, то обе функции можно заменить одной. В данном случае на роль значения по умолчанию подойдет указатель со значением 0:
move( int, int, char* = 0 );
Применять те или иные возможности следует тогда, когда этого требует логика приложения. Вовсе не обязательно включать перегруженные функции в программу только потому, что они существуют.
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКЧитайте также
Что надо для загрузки loadkeys скриптов?
Что надо для загрузки loadkeys скриптов? Если вы решили вкомпилить вашу раскладку (keymap) напрямую в ядро, вернитесь в конец 6-й главы, где вам четко сказано, что не требуется его (скрипт) запускать, если вы уже вкомпилили раскладку (keymap) в ядро. Но вы можете запустить крипт если
17.1. Что такое ядро и когда его надо менять
17.1. Что такое ядро и когда его надо менять Каждый, кто хоть немного интересовался тем, что такое Linux, обязательно встречал в различных руководствах термин "ядро", по-английски - kernel. Ядро - это важнейшая часть Linux, как и любой другой операционной системы, поскольку именно ядро
17.4.2 Что надо знать до начала компиляции
17.4.2 Что надо знать до начала компиляции Пожалуй, самое первое, к чему нужно быть готовым, приступая к компиляции ядра, - это то, что процедура эта длительная. Так что не рассчитывайте скомпилировать ядро "между делом", в свободную минутку. Заранее планируйте, что потратите
Сколько надо времени?
Сколько надо времени? Каждому хочется сделать большую и активную группу на Facebook как можно быстрее. Даже когда число друзей в нашей группе росло на 1500 человек в сутки, я считал, что это ужасно медленно! Чтобы вывести в лидеры среди компаний в России группу ESET NOD32 Russia, нашей
Сколько надо денег?
Сколько надо денег? Мне и моим коллегам удалось, не потратив ни копейки, создать две группы по 100 000 друзей. В нашей компании не было бюджета на Facebook, поэтому мы изначально искали способы, как набрать друзей без денег и без рекламы на Facebook или где-то еще. Вы не хуже нас и
Что надо публиковать?
Что надо публиковать? Если вам кажется, что публиковать нечего, вы сильно ошибаетесь. У любой компании масса новостей, независимо от возраста и масштаба бизнеса. Вот далеко не полный перечень того, о чем вы можете рассказывать на страницах вашей группы Facebook:– Выпуск,
Что и зачем надо замерять
Что и зачем надо замерять Достаточно серьезной ошибкой является попытка выполнить замеры полученных результатов после внедрения нескольких технологий. Например, вы внесли ряд изменений на главную страницу интернет-магазина и кое-что изменили на странице с корзиной
Правило 24: Объявляйте функции, не являющиеся членами, когда преобразование типов должно быть применимо ко всем параметрам
Правило 24: Объявляйте функции, не являющиеся членами, когда преобразование типов должно быть применимо ко всем параметрам Во введении я отмечал, что в общем случае поддержка классом неявных преобразований типов – неудачная мысль. Но, конечно, из этого правила есть
Правило 46: Определяйте внутри шаблонов функции, не являющиеся членами, когда желательны преобразования типа
Правило 46: Определяйте внутри шаблонов функции, не являющиеся членами, когда желательны преобразования типа В правиле 24 объясняется, почему только к свободным функциям применяются неявные преобразования типов всех аргументов. В качестве примера была приведена функция
9.1.1. Зачем нужно перегружать имя функции
9.1.1. Зачем нужно перегружать имя функции Как и в случае со встроенной операцией сложения, нам может понадобиться набор функций, выполняющих одно и то же действие, но над параметрами различных типов. Предположим, что мы хотим определить функции, возвращающие наибольшее
13.3.1. Когда использовать встроенные функции-члены
13.3.1. Когда использовать встроенные функции-члены Обратите внимание, что определения функций home(), get(), height() и width() приведены прямо в теле класса. Такие функции называются встроенными. (Мы говорили об этом в разделе 7.6.)Функции-члены можно объявить в теле класса встроенными и
10. Когда открыть, а когда закрыть
10. Когда открыть, а когда закрыть Рассмотрев деловые модели, которые поддерживают разработку программного обеспечения с открытыми текстами, мы можем теперь приблизиться к общему вопросу о том, когда исходному коду, с точки зрения экономики, имеет смысл быть «открытым», а
Надо ли заботиться о памяти?
Надо ли заботиться о памяти? Другой аргумент, который можно услышать в оправдание несерьезному подходу, - это постоянный рост объема доступной памяти компьютера и уменьшение цены памяти.Используемая память может быть как виртуальной, так и реальной. В системах