Это правило не применяется к конструкторам и функциям перегрузки операций.
Перегрузка функций, подобно многим другим свойствам Си++, была добавлена к этому языку по особым причинам. Не позволяйте себя увлечь этим. Функции, которые делают разные вещи, должны иметь и разные имена.
Перегруженные функции обычно вызывают больше проблем, чем их решают. Во-первых, проблема двусмысленности:
f( int, long
);
f( long, int
);
f( 10, 10 ); // ОШИБКА: Какую из функций я вызываю?
Более коварно следующее:
f( int );
f( void* );
f( 0 ); // ОШИБКА: Вызов двусмысленный
Проблемой здесь является Си++, который считает, что 0
может быть как указателем, так и типом int. Если вы делаете так:
const void
*NULL = 0;
const int ZERO = 0;
то вы можете записать f(NULL) для выбора варианта с указателем и f(ZERO) для доступа к целочисленному варианту, но это ведет к большой путанице. В такой ситуации вам бы лучше просто использовать функции с двумя разными именами.
Аргументы по умолчанию, создающие на самом деле перегруженные функции (по одной на каждую возможную комбинацию аргументов), также вызывают проблемы. Например, если вы написали:
f( int x = 0 );
и затем случайно вызвали f() без аргументов, компилятор успешно и без возражений вставит 0. Все, чего вы добились, — это устранили то, что в ином случае вызвало бы полезное сообщение об ошибке во время компиляции, и сдвинули ошибку на этап выполнения.
Исключениями из сказанного выше являются перегруженные операции и конструкторы; многие классы имеют их по нескольку, и аргументы по умолчанию часто имеют смысл в конструкторах. Код, подобный следующему, вполне приемлем:
class string
{
public:
string( char *s = "" );
string( const string &r );
string( const CString &r ); // преобразование из класса MFC.
// ...
};
Для пояснения: разные классы будут часто обрабатывать одно и то же сообщение, реализуя функции-обработчики с совпадающими именами. Например, большинство классов реализуют сообщение print(). Смысл того, что я пытаюсь здесь добиться, такой: плохая мысль - в одном классе иметь много обработчиков сообщений с одним и тем же именем. Вместо: