Правила программирования на Си и Си++

Конструкторы, не предназначенные


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

имени, потому что он используется только для выбора функции.



Содержание раздела