Sdílet prostřednictvím


Uživatelem definované převody (C++/CLI)

Tato část popisuje uživatelem definované převody (UDC), pokud jeden z typů v převodu je odkaz nebo instance typu hodnoty nebo referenčního typu.

Implicitní a explicitní převody

Převod definovaný uživatelem může být implicitní nebo explicitní. UDC by měl být implicitní, pokud převod nezpůsobí ztrátu informací. Jinak by se mělo definovat explicitní UDC.

Konstruktor nativní třídy lze použít k převodu odkazu nebo typu hodnoty na nativní třídu.

Další informace opřevodchchch

// 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);
}

Výstup

in N::N
in N::N

Operátory Convert-From

Převod operátorů vytvoří objekt třídy, ve které je operátor definován z objektu některé jiné třídy.

Standard C++ nepodporuje převod z operátorů; Standard C++ používá pro tento účel konstruktory. Při použití typů CLR ale Visual C++ poskytuje syntaktickou podporu volání operátorů převodu z operátorů.

Pokud chcete dobře spolupracovat s jinými jazyky odpovídajícími cls, můžete chtít zabalit každý uživatelem definovaný unární konstruktor pro danou třídu s odpovídajícím operátorem convert-from.

Převod operátorů:

  • Musí být definovány jako statické funkce.

  • Může být buď implicitní (pro převody, které nepřijdou o přesnost, jako je zkratka na int), nebo explicitní, pokud může dojít ke ztrátě přesnosti.

  • Vrátí objekt obsahující třídy.

  • Musí mít typ "from" jako jediný typ parametru.

Následující ukázka ukazuje implicitní a explicitní operátor převodu definovaný uživatelem (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);
}

Výstup

in operator
in constructor
10
1

Převod na operátory

Convert-to operators convert an object of the class in which the operator is defined to some other object. Následující ukázka ukazuje implicitní operátor převodu na převod definovaný uživatelem:

// 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);
}

Výstup

10

Explicitní uživatelem definovaný operátor převodu na převod je vhodný pro převody, které potenciálně ztratí data nějakým způsobem. Chcete-li vyvolat explicitní operátor convert-to, je nutné použít přetypování.

// 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);
}

Výstup

10.3
10

Převod obecných tříd

Obecnou třídu můžete převést na 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) );
}

Výstup

True

Převáděcí konstruktor přebírá typ a používá ho k vytvoření objektu. Konvertující konstruktor je volána pouze s přímým inicializací; casts will not invokeing converting constructors. Ve výchozím nastavení jsou převod konstruktory explicitní pro typy 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);
}

Výstup

5
R

V této ukázce kódu dělá implicitní statická konverzní funkce totéž jako explicitní konstruktor převodu.

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);
}

Výstup

13
12
500
2000

Viz také

Třídy a struktury