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