Конструкторы, не предназначенные
Си++ использует конструкторы для преобразования типов. Например, конструктор char* в 9-ой строке листинга 7 на странице 155
также обрабатывает следующую операцию приведения:
char *pchar = "абвг";
(string) pchar;
Запомните, что приведение является операцией времени выполнения, которая создает временную переменную нужного типа и инициализирует ее из аргумента. Если приводится класс, то для инициализации используется конструктор. Следующий код работает прекрасно, потому что строковая константа char*
беспрепятственно преобразуется в string для передачи в функцию f():
f( const string s );
// ...
f( "белиберда" );
Проблема состоит в том, что мы иногда не желаем использовать конструктор для неявного преобразования типов. Рассмотрим следующий контейнер массива, которым поддерживается целочисленный конструктор, определяющий размер этого массива:
class array
{
// ...
public:
array( int
initial_size );
};
Вероятно вы все же не захотите, чтобы следующий код работал:
f( const array a );
// ...
f( isupper(*str) );
(Этот вызов передает f()
пустой одноэлементный массив, если *str
состоит из заглавных букв, или массив без элементов, если *str
— из строчных букв).
Единственным способом подавления такого поведения является добавление второго аргумента в конструктор, потому что конструкторы с несколькими аргументами никогда не используются неявно:
class array
{
// ...
public:
enum bogus { set_size_to };
array( bogus, int
initial_size );
};
array ar( array::set_size_to, 128 );
Это по настоящему уродливо, но у нас нет выбора. Заметьте, что я не дал аргументу bogus
имени, потому что он используется только для выбора функции.