Язык программирования C++. Вводный курс



.Выбор преобразования A - часть 3


// ошибка: можно применить как float(), так и int()

long lval = num;

Для трансформации num в значение типа long

применимы две такие последовательности:

1.      operator float() -> стандартное преобразование

2.      operator

int()

-> стандартное преобразование

Поскольку в обоих случаях за использованием конвертера следует применение стандартного преобразования, то обе последовательности одинаково хороши и компилятор не может выбрать ни одну из них.

С помощью явного приведения типов программист способен задать нужное изменение:

// правильно: явное приведение типа

long lval = static_cast< int >( num );

Вследствие такого указания выбирается конвертер Token::operator int(), за которым следует стандартное преобразование в long.

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

class SmallInt {

public:

   SmallInt( const Number & );

   // ...

};

class Number {

public:

   operator SmallInt();

   // ...

};

extern void compute( SmallInt );

extern Number num;

compute( num );  // ошибка: возможно два преобразования

Аргумент num

преобразуется в тип SmallInt

двумя разными способами: с помощью конструктора SmallInt::SmallInt(const Number&) либо с помощью конвертера Number::operator SmallInt(). Поскольку оба изменения одинаково хороши, вызов считается ошибкой.

Для разрешения неоднозначности программист может явно вызвать конвертер класса Number:

// правильно: явный вызов устраняет неоднозначность

compute( num.operator SmallInt() );

Однако для разрешения неоднозначности не следует использовать явное приведение типов, поскольку при отборе преобразований, подходящих для приведения типов, рассматриваются как конвертер, так и конструктор:

compute( SmallInt( num ) );  // ошибка: по-прежнему неоднозначно

Как видите, наличие большого числа подобных конвертеров и конструкторов небезопасно, поэтому их.  следует применять с осторожностью. Ограничить использование конструкторов при выполнении неявных преобразований (а значит, уменьшить вероятность неожиданных эффектов) можно путем объявления их явными.




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