Правила программирования на С и С++. Главы 7-8
Страница 45. Конструкторы, не предназначенные для преобразования типов, должны иметь два или более аргумента


 

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 имени, потому что он используется только для выбора функции.

 
« Предыдущая статья   Следующая статья »