Глава 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("Спасибо, доктор Седгевик!"));

// Явное предписание создать временный объект