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