Поделиться через


Изменение операторов преобразования

Синтаксис операторов преобразования в Visual C++ 2010 изменился по сравнению с синтаксисом, используемым в управляемых расширениях C++.

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

__gc struct MyDouble {
   static MyDouble* op_Implicit( int i ); 
   static int op_Explicit( MyDouble* val );
   static String* op_Explicit( MyDouble* val ); 
};

Здесь говорится, что алгоритм преобразования целого числа в тип MyDouble предоставляется оператором op_Implicit. Более того, такое преобразование будет выполнено компилятором неявно. Подобно этому, алгоритмы преобразования объекта MyDouble либо в целое число, либо в управляемую сущность String предоставляются двумя операторами op_Explicit. Однако компилятор не будет выполнять преобразование до тех пор, пока не будет явного запроса от пользователя.

В C# это имеет следующий вид:

class MyDouble {
   public static implicit operator MyDouble( int i ); 
   public static explicit operator int( MyDouble val );
   public static explicit operator string( MyDouble val ); 
};

Код C# больше похож на C++, чем управляемые расширения C++. В новом синтаксисе такого нет.

Комитет ISO-C++ ввел ключевое слово explicit, чтобы смягчить возможные непреднамеренные последствия, например, класс Array, который принимает один целочисленный аргумент в качестве измерения, неявно преобразует любое целое число в объект Array, который является не тем, что ожидается в результате. Одним из способов предотвращения этого является создание фиктивного второго аргумента для конструктора.

С другой стороны, не следует предоставлять пару преобразования при разработке типа класса в C++. Лучшим примером этого является обычный класс строк. Неявное преобразование — это конструктор с одним аргументом, принимающий строку в формате С. Однако он не предоставляет соответствующий неявный оператор преобразования (для преобразования строкового объекта в строку в формате С, а требует от пользователя явного вызова функции по имени, в данном случае — c_str().

Поэтому связывание неявного/явного поведения в отношении оператора преобразования (и как вложение ряда преобразований в одну форму объявления) представляет собой улучшенную изначальную поддержку C++ операторов преобразования, которая привела к возникновению ключевого слова explicit. Поддержка языка Visual C++ 2010 для операторов преобразования выглядит следующим образом и имеет более краткую форму, чем в C#, благодаря поведению по умолчанию операторов, поддерживающих неявное применение алгоритма преобразования:

ref struct MyDouble {
public:
   static operator MyDouble^ ( int i );
   static explicit operator int ( MyDouble^ val );
   static explicit operator String^ ( MyDouble^ val );
};

Еще одно изменение заключается в том, что единый конструктор аргумента рассматривается как объявленный в качестве explicit. Это означает, что для инициирования его вызова требуется явное приведение. Следует заметить, что, если явный оператор преобразования определен, то вызывается он, а не конструктор с одним аргументом.

См. также

Основные понятия

Объявления членов в пределах класса или интерфейса