Benutzerdefinierte Konvertierungen (C++/CLI)
Dieser Abschnitt erläutert benutzerdefinierte Konvertierungen (UDC) wenn einer der Typen in der Konvertierung ein Verweis oder eine Instanz eines Werttyps oder des Verweistyps ist.
Implizite und explizite Konvertierungen
Eine benutzerdefinierte Konvertierung kann entweder implizit oder explizit sein.Ein UDC sollte implizit sein, wenn die Konvertierung kein Informationsverlust ergibt.Andernfalls sollte ein expliziter UDC definiert werden.
Konstruktor einer kann der systemeigene Klasse verwendet werden, um einen Verweis oder einen Werttyp zu einer systemeigenen Klasse zu konvertieren.
Weitere Informationen über Konvertierungen, finden Sie unter Implizites Boxing und Standardkonvertierungen.
// 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);
}
Ausgabe
CONVERT-Von Operators
CONVERT-von operators erstellen ein Objekt der Klasse, in der der Operator von einem Objekt einer anderen Klasse definiert ist.
Standard-C++ unterstützt nicht CONVERTvon operators; Standard-C++-Verwendungskonstruktoren zu diesem Zweck.Wenn sie CLR-Typen verwendet, bieten Visual C++ syntaktische Unterstützung zum Aufrufen von CONVERTvon operators.
Um zu gut mit anderen CLS-kompatiblen Sprachen, können Sie jeden benutzerdefinierten unären Konstruktor für eine angegebene Klasse mit entsprechenden CONVERTvon Adressoperator umschließen.
CONVERT-von operators:
Die wird als statische Funktionen definiert.
Kann entweder implizit (für Konvertierungen, die Genauigkeit nicht wie Kurz-zuint verlieren) oder explizit sein, wenn es möglicherweise ein Genauigkeitsverlust gibt.
Gibt ein - Objekt der enthaltenden Klasse zurück.
Hat "" vom Typ als einziger Parametertyp.
Das folgende Beispiel zeigt einen impliziten und expliziten "CONVERT-von", benutzerdefinierten Operator der Konvertierung (UDC) an.
// 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);
}
Ausgabe
CONVERT-zu den Operatoren
CONVERT-zuden Operatoren konvertieren Sie ein Objekt der Klasse, in der der Operator zu einem anderen Objekt definiert ist.Im folgenden Beispiel wird ein implizites, CONVERT-zu, benutzerdefinierter Konvertierungsoperator an:
// 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);
}
Ausgabe
Ein explizites benutzerdefiniertes CONVERT-zum Konvertierungsoperator ist für Konvertierungen geeignet, die möglicherweise Daten auf irgendeine Weise verlieren.Um ein explizites CONVERT-zum Operator aufzurufen, muss eine Umwandlung verwendet werden.
// 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);
}
Ausgabe
So generische Klassen konvertieren
Sie können eine generische Klasse zu T konvertieren.
// 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) );
}
Ausgabe
Ein konvertierender Konstruktor akzeptiert einen Typ und verwendet diesen, um ein - Objekt zu erstellen.Ein konvertierender Konstruktor wird nur mit direkten Initialisierung aufgerufen; Umwandlungen rufen nicht das Konvertieren von Konstruktoren auf.Standardmäßig Konstruktoren Projektsformats sind für CLR-Typen explizit.
// 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);
}
Ausgabe
In diesem Codebeispiel führt eine implizite statische Konvertierungsfunktion die gleiche Aufgabe wie ein Konstruktor der expliziten Konvertierung.
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);
}
Ausgabe