Глава 8. Раскрытие выражений_________________________________187
ния. Ниже мы рассмотрим, на что еще способен компилятор и что не всегда очевидно для программистов.
Правило одного преобразования
В C++ для того, чтобы тип аргумента соответствовал объявлению функции, достаточно одного преобразования. Ниже это и будет называться правилом одного преобразования (single conversion rule). Одно из требований C++ — объявление (или определение, — прим. перев.) функции до ее первого употребления в программе. Именно для этих целей и было принято соглашение об объявлении функций в файлах заголовков и последующем включении таких файлов в программные модули.
Что происходит когда нет "точно" соответствующего функции объявления? В C++, чтобы объявление стало соответствовать используемому коду, делается единственное преобразование, но только в том случае, если для такого преобразования есть определенные условия. Например, пусть имеется функция print:
void Print( String) ;
которая в качестве аргумента использует некий тип String воображаемого класса string. Теперь в языке появилось определение класса String (см. главу 21). Что бы произошло, если бы пользователь вызвал функцию следующим образом:
Print( "Спасибо, доктор Седгевик!"); /
Ответить на этот вопрос можно другим вопросом: "Есть ли возможность преобразовать тип char* в тип String?" Если есть, то компилятор может создать временный объект класса String и вызов функции будет правильным.
Замечание
В одиночном преобразовании типов обычно задействован конструктор. Определив конструктор таким образом:
String( const char*) ;
ИЛИ:
String) char*);
мы делаем возможным вызов временного объекта нужного типа. В главе 14 "Базовые концепции классов" конструкторы и деструкторы объяснены подробнее.
Можно записать это же выражение в явном виде — результат будет тем же. Выглядит это следующим образом:
Print ( String("Спасибо, доктор Седгевик!"));
// Явное предписание создать временный объект