Freigeben über


Benutzerdefinierte Konvertierungen

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

Benutzerdefinierte Konvertierung kann entweder implizit oder explizit sein. Ein UDC sollte implizit sein, wenn die Konvertierung kein Informationsverlust führt. Andernfalls sollte ein expliziter UDC definiert werden.

Konstruktor kann einer der systemeigene Klasse verwendet werden, um einen Verweis oder einen Werttyp zu einer systemeigenen Klasse zu konvertieren.

Weitere Informationen über Konvertierungen, finden Sie unter Boxing (Komponentenerweiterungen für C++) 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-From-Operatoren

Convert-from-Operatoren erstellen ein Objekt der Klasse, in der der Operator von einem Objekt einer anderen Klasse definiert wird.

Standard-C++ unterstützt nicht convert-from-Operatoren; Standard-C++-Verwendungskonstruktoren zu diesem Zweck. Wenn, CLR verwenden, gibt, Visual C++ bietet syntaktische Unterstützung zum Aufrufen von convert-from-Operatoren ein.

Um sich mit anderen CLS-kompatiblen Sprachen einbeziehen, können Sie jeden benutzerdefinierten unären Konstruktor für eine angegebene Klasse mit einem entsprechenden convert-from-Operator umschließen.

Convert-from-Operatoren:

  • Wird als statische Funktionen definiert.

  • Kann entweder implizit (für Konvertierungen, die Genauigkeit nicht wie Kurz-zuint verlieren) oder explizit sein, wenn es einen Genauigkeitsverlust gibt.

  • Gibt ein Objekt der enthaltenden Klasse zurück.

  • Hat "von" Typ1 als einziger Parametertyp.

Im folgenden Beispiel wird implizites und explizites "convert-from", benutzerdefinierten Konvertierungs (udc)- Operator 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 wird. Das folgende Beispiel zeigt 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 Konvertierungsoperators ist für Konvertierungen geeignet, die ggf. Daten auf eine bestimmte 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 konvertieren generische Klassen

Sie können eine generische Klasse zu konvertieren. 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) );
}

Ausgabe

  

Ein konvertierender Konstruktor akzeptiert einen Typ und verwendet diesen, um ein Objekt zu erstellen. Ein konvertierender Konstruktor wird nur mit direkten Initialisierung bezeichnet; Typumwandlungen rufen nicht das Konvertieren von Konstruktoren auf. Standardmäßig Konvertieren sind Konstruktoren 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

Klassen und Strukturen (Komponentenerweiterungen für C++)