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