Изменение операторов преобразования
Синтаксис операторов преобразования в 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. Это означает, что для инициирования его вызова требуется явное приведение. Следует заметить, что, если явный оператор преобразования определен, то вызывается он, а не конструктор с одним аргументом.