372 ___ ____ ____ Часть III. Современное программирование на C++
17:. // как вариант, возможна реализация в виде:
18: // strcpy ( name = new[ strlen(str) + 1 ], str) ;
19: }
В строке 4 объявлен конструктор, принимающий два аргумента с начальными значениями: целое и указатель на строку. Определение конструктора содержится в строках 11—19. В строке 18 приведен однострочный вариант реализации строк 13—16. C++, как и С, позволяет при желании писать весьма лаконичный код; это и благодать, и проклятие для программистов.
Присваивание начальных значений данным-членам в этом примере происходит самым привычным образом, член за членом, как оно выглядело бы и в любом другом языке. Но в C++ этот способ не единственный. Добавив для удобства глобальную функцию дублирования строк, можно переписать конструктор класса SNAFU с использованием списка инициализации (initialization list) (см. листинг 15.4).
char * Strdup ( const char* str) { //не забывайте, что вызывающая программа становится
// ответственной за освобождение памяти
char* s;
s = new char [ str-len(str) + 1 ];
if ( s) strcpy ( s, str) ;
return s;
)
// Намного более короткий конструктор, использующий список инициализации
SNAFU::SNAFU ( int n, char* str) : num(n), name(Strdup(str)){}
Конструктор стал намного проще и короче, и достигнуто это более тонким способом. С помощью списков инициализации нередко можно существенно оптимизировать задание начальных значений аргументам сложных типов. Инициализация также требуется в случае, когда класс содержит постоянные (const) данные-члены. Дальнейшее обсуждение примеров скрытых операций, происходящих без видимых признаков, содержится в главе 17 "Конструкторы: копирование и присваивание". Константы подробно рассмотрены в главе 9 "Описатели и спецификаторы данных".
Перегрузка и аргументы по умолчанию
Перегрузка выполняется автоматически: когда функции имеют одинаковые имена, но отличающиеся аргументы, компилятор строит из комбинации имени и типов аргументов уникальный идентификатор. Аргументы по умолчанию — это начальные значения, которые программист может присвоить аргументам, если они известны.