Sdílet prostřednictvím


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

Tato část pojednává o uživatelem definovaný převod (UDC), pokud je jeden z typů při převodu odkaz nebo instance hodnotového typu nebo typ odkazu.

Implicitní a explicitní převody

Uživatelem definovaný převod může být buď implicitní nebo explicitní.UDC by měla být implicitní, pokud převod nemá za následek ztrátu informací.V opačném případě je třeba definovat explicitní UDC.

Konstruktor nativní třídy slouží k převedení typu hodnotou nebo odkazem na nativní třídy.

Další informace o převodech naleznete v tématu Zabalení (rozšíření komponent C++) a Standardní.

// 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ýsledek

  

Převod z operátorů

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

Standard C++ nepodporuje převod z hospodářskými subjekty; Standard C++ používá konstruktory pro tento účel.Však při použití typy CLR, Visual C++ podporují syntaktické volání převést z operátorů.

Spolupracovat i s jinými jazyky odpovídající specifikaci CLS, budete pravděpodobně chtít zabalit každému konstruktoru unární uživatelem definované pro dané třídy s odpovídající operátor převodu z.

Převod z operátorů:

  • Rozumí statické funkce.

  • Může být (pro převody, které nepřišli o přesnosti jako short int) implicitní nebo explicitní, pokud mohou být ztrátu přesnosti.

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

  • Musí mít typ "z" jako jediný parametr typu.

Následující ukázka představuje implicitní a explicitní "convert z", uživatelem definovaný převod (UDC) operátor.

// 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ýsledek

  

Převést na operátory

Převést na operátory převést objekt třídy, ve kterém je definován operátor na některý jiný objekt.Následující příklad ukazuje implicitní, převést do, uživatelem definovaný převod operátor:

// 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ýsledek

  

Explicitní uživatelem definovaný převod na operátor převodu je vhodné pro převody, které by dojít ke ztrátě dat nějakým způsobem.Vyvoláte explicitní operátor převodu, musíte 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ýsledek

  

Chcete-li převést obecné třídy

Je možné převést obecnou třídu 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ýsledek

  

Převod konstruktor přebírá typu a používá k vytvoření objektu.Převod konstruktoru je volána s přímé inicializace nádech se nemůže dovolávat převod konstruktory.Ve výchozím nastavení jsou explicitní typy CLR převod konstruktory.

// 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ýsledek

  

V této ukázce kódu implicitní převod statické funkce provede stejnou akci jako konstruktor explicitní převod.

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ýsledek

  

Viz také

Referenční dokumentace

Třídy a struktury (rozšíření komponent C++)