Partager via


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

  

Voir aussi

Référence

Classes et structs (extensions du composant C++)