Partager via


Vue d'ensemble de génériques dans Visual C++

Les génériques sont des types paramétrables pris en charge par le common langage runtime.Un type paramétré est un type défini avec un paramètre de type inconnu qui est spécifiée lorsque le générique est utilisé.

pourquoi génériques ?

Modèles en charge C++ et modèles et types paramétrables de prise en charge des génériques pour créer des classes de collections typées.Toutefois, les modèles fournissent le paramétrage de compilation.Vous ne pouvez pas référencer un assembly qui contient une définition de modèle et de créer des spécialisations du modèle.Une fois compilé, un modèle spécialisé ressemble à n'importe quelle autre classe ou méthode.En revanche, les génériques sont émis dans le langage MSIL en tant que type paramétrable connu par le runtime pour être un type paramétrable ; code source qui référence un assembly contenant un type générique peut créer des spécialisations du type générique.Pour plus d'informations sur la comparaison des modèles et des génériques Visual C++, Génériques et modèles (Visual C++)consultez.

Fonctions et types génériques

Les types de classe, à condition que ils sont des types managés, peuvent être génériques.Un exemple de ce peut être une classe d' List .Le type d'un objet de la liste est le paramètre de type.Si vous nécessaire une classe d' List pour de nombreux types d'objets, avant que les génériques vous pouvez utiliser List qui prend System::Object comme type d'élément.Mais cela permettrait tout objet (notamment les objets du type incorrect) à utiliser dans la liste.Une telle liste est appelée une classe de collection non typée.Au mieux, vous pouvez vérifier le type au moment de l'exécution et lever une exception.Ou, vous pouvez avoir utilisé un modèle, qui perdrait sa qualité générique une fois compilée dans un assembly.Les utilisateurs de votre assembly ne soient pas créer leurs propres spécialisations du modèle.Les génériques vous permettent de créer des classes de collections typées, de déterminer List<int> (lecture en tant que « liste d'int ») etList<double> (« liste de double ») qui généraient une erreur de compilation si vous essayez de mettre un type que la collection n'a pas été conçue pour recevoir dans la collection typée.En outre, ces types restent génériques après leur compilation.

Une description de la syntaxe des classes génériques peut être récupérée dans Classes génériques (C++/CLI)le nouvel espace de noms d'.Un, System.Collections.Generic, introduit un ensemble de types de collection paramétrées y compris Dictionary<TKey, TValue>, List<T> et LinkedList<T>.Consultez Génériques dans la bibliothèque de classes .NET Framework (Guide de programmation C#) pour plus d'informations.

Les fonctions membres d'instance et de classe statique, des délégués, et les fonctions globales peuvent également être génériques.Les fonctions génériques peuvent être nécessaires si les paramètres de la fonction sont d'un type inconnu, ou si la fonction elle-même doit s'exécuter avec les types génériques.Dans de nombreux cas où System::Object peut avoir été utilisé dans le passé comme paramètre pour un type d'objet inconnu, un paramètre de type générique peut être utilisé à la place, autorisant de code plus type-safe.Toute tentative de passer dans un type que la fonction n'a pas été conçue pour est marquée en tant qu'erreur au moment de la compilation.À l'aide de System::Object comme paramètre de fonction, passer négligent d'un objet lequel la fonction n'a pas été conçue pour traiter n'est pas détecté, et vous devez effectuer un cast du type d'objet inconnu en un type spécifique dans le corps de la fonction, et expliquent la possibilité d'un InvalidCastException.Avec un générique, le code d'une tentative de passer un objet à la fonction provoquerait un conflit de type afin que le corps de la fonction est assuré d'avoir le type correct.

Les mêmes avantages s'appliquent aux classes de collection basées sur des génériques.les classes de collection dans le passé emploieraient System::Object pour enregistrer des éléments dans une collection.La mise en place des objets d'un type que la collection n'a pas été conçue pour n'a pas été marquée pour un indicateur au moment de la compilation, et souvent pas même lorsque les objets ont été insérés.Généralement, un objet est casté en un autre type lorsqu'il a fait l'objet d'un accès dans la collection.Uniquement lorsque le cast a échoué le type inattendu serait détecté.Les génériques résoudre ce problème au moment de la compilation en détectant tout code qui insère un type qui ne correspond pas (ou convertir implicitement) le paramètre de type de la collection générique.

Pour une description de la syntaxe, consultez Fonctions génériques (C++/CLI).

Terminologie utilisée avec les génériques

c570k3f3.collapse_all(fr-fr,VS.110).gifParamètres de type

Une déclaration générique contient un ou plusieurs types inconnus appelés paramètres de type.Les paramètres de type portent un nom qui représente le type dans le corps de la déclaration générique.Le paramètre de type est utilisé comme type dans le corps de la déclaration générique.la déclaration générique pour la liste <T> contient le paramètre de type T.

c570k3f3.collapse_all(fr-fr,VS.110).gifarguments de type

L'argument de type est le type réel utilisé à la place du paramètre de type lorsque le générique est spécialisé pour un type spécifique ou types.par exemple, int est l'argument de type dans List<int>.Les types valeur et les types de handle sont les seuls types autorisés en tant qu'argument de type générique.

c570k3f3.collapse_all(fr-fr,VS.110).giftype construit

Un type construit d'un type générique est appelé un type construit.Un type pas complètement spécifié, comme List<T> est un type construit ouverte; un type complètement spécifié, comme List<double>, est un type construit fermé ou type spécialisé.Open a construit des types peut être utilisé dans la définition d'autres types et méthodes génériques et ne peut être complètement spécifié jusqu'à ce que le générique englobant lui-même est spécifié.Par exemple, voici une utilisation d'un type construit ouvert comme classe de base pour un générique :

// generics_overview.cpp

// compile with: /clr /c

generic <typename T>

ref class List {};

generic <typename T>

ref class Queue : public List<T> {};

c570k3f3.collapse_all(fr-fr,VS.110).gifContrainte

Une contrainte est une restriction sur les types qui peuvent être utilisés comme paramètre de type.Par exemple, une classe générique donnée peut accepter uniquement les classes qui héritent d'une classe spécifiée, ou implémentent une interface spécifiée.Pour plus d'informations, consultez Contraintes sur les paramètres de type générique (C++/CLI).

types référence et types valeur

Les handles types et les types valeur peuvent être utilisés comme arguments de type.Dans la définition générique, dans laquelle l'un ou l'autre type peut être utilisé, la syntaxe est celle des types référence.Par exemple, l'opérateur de -> est utilisé pour accéder aux membres du type du paramètre de type si le type par la suite utilisé est un type référence ou un type valeur.Lorsqu'un type valeur est utilisé comme argument de type, le runtime génère du code qui utilise des types valeur directement sans exécuter un boxing des types valeur.

Lorsque vous utilisez un type référence en tant qu'argument de type générique, utilisez la syntaxe de handle.Lorsque vous utilisez un type valeur en tant qu'argument de type générique, utilisez le nom de type directement.

// generics_overview_2.cpp

// compile with: /clr

generic <typename T>

ref class GenericType {};

ref class ReferenceType {};

value struct ValueType {};

int main() {

GenericType<ReferenceType^> x;

GenericType<ValueType> y;

}

Paramètres de type

Les paramètres de type dans une classe générique sont traités comme d'autres identificateurs.Toutefois, étant donné que le type n'est pas connu, il existe des restrictions sur leur utilisation.Par exemple, vous ne pouvez pas utiliser des membres et les méthodes de la classe de paramètre de type à moins que le paramètre de type est connu pour prendre en charge ces membres.Autrement dit, pour accéder à un membre par le biais de le paramètre de type, vous devez ajouter le type qui contient le membre à la liste de contraintes de paramètre de type.

// generics_overview_3.cpp

// compile with: /clr

interface class I {
   void f1();
   void f2();
};

ref struct R : public I {
   virtual void f1() {}
   virtual void f2() {} 
   virtual void f3() {} 
};

generic <typename T>
where T : I
void f(T t) {
   t->f1();
   t->f2();
   safe_cast<R^>(t)->f3();
}

int main() {
   f(gcnew R());
}

ces restrictions s'appliquent aux opérateurs également.Un paramètre de type générique sans contrainte ne peut pas utiliser les opérateurs d' == et d' != pour comparer deux instances du paramètre de type, au cas où le type ne prendrait pas en charge ces opérateurs.Ces contrôles sont nécessaires pour les génériques, mais pas aux modèles, car les génériques peuvent être spécialisés au moment de l'exécution avec toute classe qui satisfait aux contraintes, lorsqu'elle est trop tardive pour vérifier l'utilisation des membres valides.

une instance par défaut du paramètre de type peut être créée à l'aide de l'opérateur d' () .Par exemple :

T t = T();

où T est un paramètre de type dans une classe ou une définition de méthode générique, initialise la variable à sa valeur par défaut.Si T est une classe de référence il s'agit d'un pointeur null ; si T est une classe de valeur, l'objet est initialisé à zéro.Cela est appelé un initialiseur par défaut.

Voir aussi

Autres ressources

Génériques (extensions du composant C++)