Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
En esta sección se describen las conversiones definidas por el usuario (UDC) cuando uno de los tipos de la conversión es una referencia o instancia de un tipo de valor o un tipo de referencia.
Conversiones implícitas y explícitas
Las conversiones definidas por el usuario pueden ser implícitas o explícitas. Un UDC debe ser implícito si no da lugar a una pérdida de información. De lo contrario, se debe definir una UDC explícita.
El constructor de una clase nativa se puede usar para convertir un tipo de referencia o de valor en una clase nativa.
Para más información sobre las conversiones, consulte Conversión boxing y Conversiones estándar.
// mcpp_User_Defined_Conversions.cpp
// compile with: /clr
#include "stdio.h"
ref class R;
class N;
value class V {
static operator V(R^) {
return V();
}
};
ref class R {
public:
static operator N(R^);
static operator V(R^) {
System::Console::WriteLine("in R::operator N");
return V();
}
};
class N {
public:
N(R^) {
printf("in N::N\n");
}
};
R::operator N(R^) {
System::Console::WriteLine("in R::operator N");
return N(nullptr);
}
int main() {
// Direct initialization:
R ^r2;
N n2(r2); // direct initialization, calls constructor
static_cast<N>(r2); // also direct initialization
R ^r3;
// ambiguous V::operator V(R^) and R::operator V(R^)
// static_cast<V>(r3);
}
Salida
in N::N
in N::N
Operadores de conversión desde
Los operadores convert-from crean un objeto de la clase en la que el operador se define a partir de un objeto de alguna otra clase.
C++ estándar no admite operadores convert-from; C++ estándar usa constructores para este fin. Sin embargo, al usar tipos de CLR, Visual C++ proporciona soporte sintáctico para llamar a operadores de conversión desde.
Para interoperar bien con otros lenguajes conformes a CLS, puede que desee encapsular cada constructor unario definido por el usuario para una clase determinada con un operador convert-from correspondiente.
Operadores de conversión de:
Se definirán como funciones estáticas.
Pueden ser implícitas (para conversiones que no pierden precisión, como short-to-int) o explícitas, cuando puede haber una pérdida de precisión.
Devolverá un objeto de la clase contenedora.
Tendrá el tipo "from" como el único tipo de parámetro.
En el ejemplo siguiente se muestra un operador de conversión implícito y explícito "convert-from", definido por el usuario (UDC).
// clr_udc_convert_from.cpp
// compile with: /clr
value struct MyDouble {
double d;
MyDouble(int i) {
d = static_cast<double>(i);
System::Console::WriteLine("in constructor");
}
// Wrap the constructor with a convert-from operator.
// implicit UDC because conversion cannot lose precision
static operator MyDouble (int i) {
System::Console::WriteLine("in operator");
// call the constructor
MyDouble d(i);
return d;
}
// an explicit user-defined conversion operator
static explicit operator signed short int (MyDouble) {
return 1;
}
};
int main() {
int i = 10;
MyDouble md = i;
System::Console::WriteLine(md.d);
// using explicit user-defined conversion operator requires a cast
unsigned short int j = static_cast<unsigned short int>(md);
System::Console::WriteLine(j);
}
Salida
in operator
in constructor
10
1
Operadores de conversión
Los operadores convert-to convierten un objeto de la clase en la que el operador se define en algún otro objeto. En el siguiente ejemplo se muestra un operador de conversión implícita definido por el usuario.
// clr_udc_convert_to.cpp
// compile with: /clr
using namespace System;
value struct MyInt {
Int32 i;
// convert MyInt to String^
static operator String^ ( MyInt val ) {
return val.i.ToString();
}
MyInt(int _i) : i(_i) {}
};
int main() {
MyInt mi(10);
String ^s = mi;
Console::WriteLine(s);
}
Salida
10
Un operador de conversión explícito definido por el usuario es adecuado para las conversiones que podrían perder datos de algún modo. Para invocar un operador de conversión explícito, se debe usar un casting.
// clr_udc_convert_to_2.cpp
// compile with: /clr
value struct MyDouble {
double d;
// convert MyDouble to Int32
static explicit operator System::Int32 ( MyDouble val ) {
return (int)val.d;
}
};
int main() {
MyDouble d;
d.d = 10.3;
System::Console::WriteLine(d.d);
int i = 0;
i = static_cast<int>(d);
System::Console::WriteLine(i);
}
Salida
10.3
10
Para convertir clases genéricas
Puede convertir una clase genérica en T.
// clr_udc_generics.cpp
// compile with: /clr
generic<class T>
public value struct V {
T mem;
static operator T(V v) {
return v.mem;
}
void f(T t) {
mem = t;
}
};
int main() {
V<int> v;
v.f(42);
int i = v;
i += v;
System::Console::WriteLine(i == (42 * 2) );
}
Salida
True
Los constructores de conversión toman un tipo y lo usan para crear un objeto. Solo se llama a los constructores de conversión con inicialización directa; las conversiones no invocarán constructores de conversión. De forma predeterminada, los constructores de conversión son explícitos para los tipos de CLR.
// clr_udc_converting_constructors.cpp
// compile with: /clr
public ref struct R {
int m;
char c;
R(int i) : m(i) { }
R(char j) : c(j) { }
};
public value struct V {
R^ ptr;
int m;
V(R^ r) : ptr(r) { }
V(int i) : m(i) { }
};
int main() {
R^ r = gcnew R(5);
System::Console::WriteLine( V(5).m);
System::Console::WriteLine( V(r).ptr);
}
Salida
5
R
En este ejemplo de código, una función de conversión estática implícita realiza la misma función que un constructor de conversión explícito.
public value struct V {
int m;
V(int i) : m(i) {}
static operator V(int i) {
V v(i*100);
return v;
}
};
public ref struct R {
int m;
R(int i) : m(i) {}
static operator R^(int i) {
return gcnew R(i*100);
}
};
int main() {
V v(13); // explicit
R^ r = gcnew R(12); // explicit
System::Console::WriteLine(v.m);
System::Console::WriteLine(r->m);
// explicit ctor can't be called here: not ambiguous
v = 5;
r = 20;
System::Console::WriteLine(v.m);
System::Console::WriteLine(r->m);
}
Salida
13
12
500
2000