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

  

Siehe auch

Referenz

Classes and Structs (Managed)