Если можно, то делайте все преобразования типов с помощью конструкторов
Распространенной ошибкой среди начинающих программистов на Си++ является сумасбродство с преобразованием типов. Вы чувствуете, что должны обеспечить преобразование каждого системного типа в ваш новый класс и обратно. Это может привести к подобному коду:
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ж. Управление памятью