Conversions définies par l'utilisateur (C++/CLI)
Cette section traite des conversions définies par l'utilisateur (UDC) lorsque l'un des types de la conversion est une référence ou d'une instance d'un type valeur ou un type référence.
Conversions implicites ou explicites
Une conversion définie par l'utilisateur peut être implicite ou explicite.Une CDU doit être implicite si la conversion n'a pas entraîner une perte d'informations.Sinon une CDU explicite doit être définie.
Le constructeur natif d'une classe peut être utilisé pour convertir une référence ou un type valeur à une classe native.
Pour plus d'informations sur les conversions, consultez Boxing (extensions du composant C++) et le Conversions standard.
// 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);
}
Sortie
Converti-De Operators
Converti- de operators crée un objet de la classe dans lequel l'opérateur est défini d'un objet d'une autre classe.
C++ standard ne prend pas converti- de operators ; C++ standard utilise des constructeurs à cet effet.Toutefois, lorsque vous utilisez le CLR types, Visual C++ offrent une prise en charge syntaxique d'appeler converti- de operators.
Pour interagir bien avec d'autres langages conformes CLS, vous pouvez souhaiter habiller chaque constructeur unaire défini par l'utilisateur pour une classe donnée à converti- de operator correspondant.
Converti-de operators :
Est défini comme fonctions statiques.
Peut être implicite (pour les conversions qui ne perdent pas la précision par exemple le court-à- int) ou explicite, lorsqu'il peut y avoir une perte de précision.
Retourne un objet de la classe conteneur.
« A » du type comme seul type de paramètre.
L'exemple suivant montre un implicite et explicite « converti- de », opérateur défini par l'utilisateur de (UDC) de conversion.
// 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);
}
Sortie
Converti-aux opérateurs
Converti- aux opérateurs convertir un objet de la classe dans lequel l'opérateur est défini avec un autre objet.L'exemple suivant montre un implicite, converti- à, opérateur défini par l'utilisateur de conversion :
// 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);
}
Sortie
Un défini par l'utilisateur explicite converti- à l'opérateur de conversion est pertinent pour les conversions qui perdent potentiellement des données d'une certaine façon.Pour appeler un explicite converti-à l'opérateur, un cast doit être utilisé.
// 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);
}
Sortie
Pour convertir les classes génériques
Vous pouvez convertir une classe générique à 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) );
}
Sortie
Un constructeur conversion prend un type et l'utilise pour créer un objet.Un constructeur conversion est appelé avec l'initialisation directe uniquement ; les casts n'appellent pas convertir des constructeurs.Par défaut, convertissant les constructeurs sont explicites pour les types 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);
}
Sortie
Dans cet exemple de code, une fonction statique de conversion implicite est le même qu'un constructeur explicite de conversion.
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);
}
Sortie