Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
I det här avsnittet beskrivs användardefinierade konverteringar (UDC) när en av typerna i konverteringen är en referens eller instans av en värdetyp eller referenstyp.
Implicita och explicita konverteringar
En användardefinierad konvertering kan antingen vara implicit eller explicit. En UDC bör vara implicit om konverteringen inte resulterar i förlust av information. Annars bör en explicit UDC definieras.
Konstruktorn för en inbyggd klass kan användas för att konvertera en referens- eller värdetyp till en intern klass.
Mer information om konverteringar finns i Boxning och Standardkonverteringar.
// 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);
}
Resultat
in N::N
in N::N
Convert-From Operatörer
Konvertera från-operatorer skapar ett objekt i klassen där operatorn definieras från ett objekt i någon annan klass.
Standard C++ stöder inte konvertera från-operatorer. standard C++ använder konstruktorer för detta ändamål. Men när du använder CLR-typer ger Visual C++ syntaktisk support för att anropa konvertera från-operatorer.
Om du vill samverka väl med andra CLS-kompatibla språk kanske du vill omsluta varje användardefinierad unary-konstruktor för en viss klass med motsvarande convert-from-operator.
Konvertera från operatorer:
Ska definieras som statiska funktioner.
Kan antingen vara implicit (för konverteringar som inte förlorar precision, till exempel short-to-int) eller explicit, när precisionen kan gå förlorad.
Ska returnera ett objekt av den innehållande klassen.
Ska ha typen "från" som enskild parametertyp.
Följande exempel visar en implicit och explicit "convert-from", användardefinierad konverteringsoperator (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);
}
Resultat
in operator
in constructor
10
1
Konvertera till operatorer
Konvert-till-operatorer konverterar ett objekt i klassen där operatorn har definierats till ett annat objekt. Följande exempel visar en implicit, konvertera till, användardefinierad konverteringsoperator:
// 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);
}
Resultat
10
En explicit användardefinierad konverteringsoperator är lämplig för konverteringar som potentiellt förlorar data på något sätt. Om du vill anropa en explicit konverteringstilloperator måste en kastning användas.
// 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);
}
Resultat
10.3
10
Konvertera generiska klasser
Du kan konvertera en allmän klass till 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) );
}
Resultat
True
En konverterande konstruktor tar en typ och använder den för att skapa ett objekt. En konverterande konstruktor anropas endast med direkt initiering. casts anropar inte konverterande konstruktorer. Som standard är konvertering av konstruktorer explicita för CLR-typer.
// 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);
}
Resultat
5
R
I det här kodexemplet gör en implicit statisk konverteringsfunktion samma sak som en explicit konverteringskonstruktor.
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);
}
Resultat
13
12
500
2000