Правила программирования на С и С++. Главы 7-8 - Не сходите с ума с операторами преобразования типов

ОГЛАВЛЕНИЕ

 

150. Не сходите с ума с операторами преобразования типов.

151. Если можно, то делайте все преобразования типов с конструкторами.

Распространенной ошибкой среди начинающих программистов на С++ является сумасбродство с преобразованием типов. Вы чувствуете, что должны обеспечить преобразование каждого системного типа в ваш новый класс и обратно. Это может привести к подобному коду:

class riches // богачи

{

public:

riches( const rags ?r );};

class rags // оборванцы

{

public:

operator riches( void );};Проблема заключается в том, что обе функции определяют преобразование из rags в riches. Следующий код генерирует "постоянную ошибку" (которая прерывает компиляцию), потому что компилятор не знает, использовать ли ему для преобразования rags в riches конструктор в классе riches, или перегруженную операцию в классе rags; конструктор и перегруженная операция утверждают, что выполнят эту работу: rags horatio_alger; // Гораций Алгер

riches bill_gates = (riches) horatio_alger; // Бил Гейтс

Эта проблема обычно не так очевидна. Например, если вы определите слишком много преобразований: class some_class

{

public:

operator int (void);

operator const char * (void);

};то простой оператор, подобный: some_class x;

cout ?? x;

не сработает. Проблема в том, что класс stream определяет те же два преобразования: ostream ?ostream::operator??( int x );

ostream ?ostream::operator??( const char *s );

Так как имеется два варианта преобразований, то компилятор не знает, какой из них вызывать.

Лучше выполнять все преобразования типов при помощи конструкторов и определять минимально необходимый их набор. Например, если у вас есть преобразование из типа doble, то вам не нужны int, long и так далее, потому что нормальные правила преобразования типов С применяются компилятором при вызове вашего конструктора.