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



         

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 );

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

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

Часть 8ж. Управление памятью




Содержание  Назад  Вперед