Sdílet prostřednictvím


Uživatelem definované převody

Tato část popisuje uživatelem definované převody (UDC), když jeden z typů v převodu je instance typu hodnoty nebo typ odkazu a odkaz.

Implicitní a explicitní převody

Uživatelem definovaný převod může být implicitní nebo explicitní. UDC by mělo 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.

Nativní třídy konstruktor lze použít k převedení typu hodnotou nebo odkazem na nativní třídy.

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

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

  

Operátory převodu z

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í typů 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é uživatelské unární konstruktor pro danou třídu s odpovídající operátor převést z.

Převod z operátorů:

  • Jsou definovány jako statické funkce.

  • Může být buď (pro převody, které není ke ztrátě přesnosti jako short int) implicitní nebo explicitní, pokud může být ztráta přesnosti.

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

  • Musí být typu "od" jako jediný parametr.

Následující příklad ukazuje implicitní a explicitní "convert od", 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řevod provozovateli, uživatelem definovaný převod:

// 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řevést, 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ýsledek

  

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

Můžete 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žije ji k vytvoření objektu. Převod konstruktoru je volána s přímé inicializace nádech se nemůže dovolávat převod konstruktory.Standardně jsou konstruktory převod explicitní 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ýsledek

  

V této ukázce kódu implicitní převod na 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++)