Konwersje zdefiniowane przez użytkownika (C++/CLI)
W tej sekcji omówiono konwersje zdefiniowane przez użytkownika (UDC), gdy jeden z typów w wyniku konwersji jest odwołanie lub wystąpienie typu wartości lub odwołania.
Konwersje niejawne i jawne
Konwersja zdefiniowana przez użytkownika może być bezpośrednia lub pośrednia. UDC powinny być ukryte, jeśli konwersja nie powoduje utraty informacji.W przeciwnym razie należy określić jawne UDC.
Konstruktor macierzysta klasa może służyć do konwersji typu odwołanie lub wartość do macierzysta klasa.
Aby uzyskać więcej informacji na temat konwersji, zobacz Niejawne boksie i Konwersje standardowe.
// 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);
}
Dane wyjściowe
Operatory konwersji z
Operatory konwersji z utworzenia obiektu klasy, w której zdefiniowano operatora z obiektu jakiejś innej klasy.
Standard C++ nie obsługuje konwersji z podmiotami gospodarczymi; Standard C++ używa konstruktorów do tego celu.Jednak podczas korzystania z typu CLR, Visual C++ wspierać syntaktyczne operatory konwersji z wywołaniem.
Do współpracy z innych języków ze specyfikacją CLS, mogą chcieć wrap z odpowiedniego przedsiębiorcy konwersji z każdego użytkownika jednoargumentowy Konstruktor dla danej klasy.
Operatory konwersji od:
Definiuje się jako funkcji statycznej.
Albo można (dla konwersji, które nie tracą dokładność takich jak krótko int) bezpośrednia lub pośrednia, gdy mogą być utratę precyzji.
Zwraca obiekt zawierający klasy.
Posiada typu "z" jako jedyny parametr typu.
Poniższy przykład pokazuje niejawne i jawne "convert z", operator zdefiniowana przez użytkownika konwersja (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);
}
Dane wyjściowe
Operatory konwersji do
Operatory konwersji do konwersji obiektu klasy, w której zdefiniowano operatora do innego obiektu.Poniższy przykład pokazuje niejawna, Konwertuj operatorowi, zdefiniowana przez użytkownika konwersja:
// 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);
}
Dane wyjściowe
Operator konwersji jawnej użytkownika convert do jest odpowiedni dla konwersji, które może spowodować utratę danych w inny sposób.Aby wywołać jawne konwersji do operatora, musi być używany rzutu.
// 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);
}
Dane wyjściowe
Aby przekonwertować klas rodzajowych
Można przekonwertować klasą rodzajową 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) );
}
Dane wyjściowe
Konwertowanie Konstruktor ma typ i używa jej do utworzenia obiektu. Konwertowanie Konstruktor jest wywoływana z bezpośredniego inicjowania tylko; odlewy nie będzie wywoływał konwersji konstruktorów.Domyślnie konwersja konstruktory są jawne dla typu 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);
}
Dane wyjściowe
W tym przykładowym kodzie funkcję niejawna konwersja statyczne nie to samo co konstruktor konwersja jawna.
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);
}
Dane wyjściowe