Правила программирования на С и С++. Главы 7-8 - Конструкторы, не предназначенные для преобразования типов, должны иметь два или более аргумента
ОГЛАВЛЕНИЕ
Страница 45 из 74
132. Конструкторы, не предназначенные для преобразования типов, должны иметь два или более аргумента.
С++ использует конструкторы для преобразования типов. Например, конструктор char* в 9-ой строке листинга 7 на странице 111 также обрабатывает следующую операцию приведения:
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 имени, потому что он используется только для выбора функции.