Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Le Concepteur de classes affiche une surface de conception visuelle appelée diagramme de classes qui fournit une représentation visuelle des éléments de code dans votre projet. Vous pouvez utiliser des diagrammes de classes pour concevoir et visualiser des classes et d’autres types dans un projet.
Le Concepteur de classes prend en charge les éléments de code C++ suivants :
Classe (ressemble à une forme de classe managée, sauf qu’elle peut avoir plusieurs relations d’héritage)
Classe anonyme (affiche le nom généré par l’affichage de classes pour le type anonyme)
Classe modèle
Struct
Enum
Macro (affiche la vue post-traitée de la macro)
Typedef
Note
Ce n’est pas le même que le diagramme de classes UML que vous pouvez créer dans un projet de modélisation. Pour plus d’informations, consultez Diagrammes de classes UML : Référence.
Classes C++ dans le Concepteur de classes
Le Concepteur de classes prend en charge les classes C++ et visualise les classes C++ natives de la même façon que les formes de classe Visual Basic et C#, à l’exception que les classes C++ peuvent avoir plusieurs relations d’héritage. Vous pouvez développer la forme de classe pour afficher davantage de champs et de méthodes dans la classe ou la réduire pour économiser de l’espace.
Note
Le Concepteur de classes ne prend pas en charge les unions (un type spécial de classe dans lequel la mémoire allouée est uniquement la quantité nécessaire pour le membre de données le plus important de l’union).
Héritage simple
Lorsque vous faites glisser plusieurs classes sur un diagramme de classes et que les classes ont une relation d’héritage de classe, une flèche les connecte. La flèche pointe dans la direction de la classe de base. Par exemple, lorsque les classes suivantes sont affichées dans un diagramme de classes, une flèche les connecte, pointant de B à A :
class A {};
class B : A {};
Vous pouvez également faire glisser uniquement la classe B vers le diagramme de classes, cliquer avec le bouton droit sur la forme de classe pour B, puis cliquer sur Afficher les classes de base. Cela affiche sa classe de base : A.
Héritage multiple
Le Concepteur de classes prend en charge la visualisation des relations d’héritage de plusieurs classes. L’héritage multiple est utilisé lorsqu’une classe dérivée a des attributs de plusieurs classes de base. Voici un exemple d’héritage multiple :
class Bird {};
class Swimmer {};
class Penguin : public Bird, public Swimmer {};
Lorsque vous faites glisser plusieurs classes sur le diagramme de classes et que les classes ont une relation d’héritage à plusieurs classes, une flèche les connecte. La flèche pointe dans la direction des classes de base.
Cliquez avec le bouton droit sur une forme de classe, puis cliquez sur Afficher les classes de base pour la classe sélectionnée.
Note
La commande Show Derived Classes n’est pas prise en charge pour le code C++. Vous pouvez afficher des classes dérivées en accédant à l’affichage de classes, en développant le nœud de type, en développant le sous-dossier Types dérivés , puis en faisant glisser ces types dans le diagramme de classes.
Pour plus d’informations sur l’héritage de plusieurs classes, consultez Plusieurs classes d’héritage et plusieurs classes de base.
Classes abstraites
Le Concepteur de classes prend en charge les classes abstraites (également appelées « classes de base abstraites »). Il s’agit de classes que vous n’instanciez jamais, mais dont vous pouvez dériver d’autres classes. À l’aide d’un exemple de « Héritage multiple » plus haut dans ce document, vous pouvez instancier la Bird classe en tant qu’objets individuels comme suit :
int main()
{
Bird sparrow;
Bird crow;
Bird eagle;
}
Toutefois, vous n’avez peut-être pas l’intention d’instancier la Swimmer classe en tant qu’objets individuels. Vous pouvez seulement vouloir dériver d’autres types de classes animales, par exemple, Penguin, Whaleet Fish. Dans ce cas, vous déclarez la Swimmer classe en tant que classe de base abstraite.
Pour déclarer une classe comme abstraite, vous pouvez utiliser le abstract mot clé. Les membres marqués comme abstraits ou inclus dans une classe abstraite sont virtuels et doivent être implémentés par les classes qui dérivent de la classe abstraite.
class Swimmer abstract
{
virtual void swim();
void dive();
};
Vous pouvez également déclarer une classe comme abstraite en incluant au moins une fonction virtuelle pure :
class Swimmer
{
virtual void swim() = 0;
void dive();
};
Lorsque vous affichez ces déclarations dans un diagramme de classes, le nom Swimmer de la classe et sa fonction swim virtuelle pure sont affichés en italique dans une forme de classe abstraite, ainsi que la classe abstraite de notation. Notez que la forme de type de classe abstraite est la même que celle d’une classe normale, sauf que sa bordure est une ligne en pointillés.
Une classe dérivée d’une classe de base abstraite doit remplacer chaque fonction virtuelle pure dans la classe de base, ou la classe dérivée ne peut pas être instanciée. Par exemple, si vous dérivez une Fish classe de la Swimmer classe, Fish vous devez remplacer la swim méthode :
class Fish : public Swimmer
{
void swim(int speed);
};
int main()
{
Fish guppy;
}
Lorsque vous affichez ce code dans un diagramme de classes, Concepteur de classes dessine une ligne d’héritage entre Fish et Swimmer.
Classes anonymes
Le Concepteur de classes prend en charge les classes anonymes. Les types de classes anonymes sont des classes déclarées sans identificateur. Ils ne peuvent pas avoir de constructeur ou de destructeur, ne peuvent pas être passés en tant qu’arguments à des fonctions et ne peuvent pas être retournés en tant que valeurs de retour à partir de fonctions. Vous pouvez utiliser une classe anonyme pour remplacer un nom de classe par un nom typedef, comme dans l’exemple suivant :
typedef struct
{
unsigned x;
unsigned y;
} POINT;
Les structures peuvent également être anonymes. Le Concepteur de classes affiche des classes anonymes et des structures identiques à celles qui affichent le type respectif. Bien que vous puissiez déclarer et afficher des classes et structures anonymes, le Concepteur de classes n’utilise pas le nom de balise que vous spécifiez. Il utilise le nom généré par l’affichage de classes. La classe ou la structure apparaît dans la vue de classe et le Concepteur de classes en tant qu’élément appelé __unnamed.
Pour plus d’informations sur les classes anonymes, consultez Types de classes anonymes.
Classes de modèle
Le Concepteur de classes prend en charge la visualisation des classes de modèle. Les déclarations imbriquées sont prises en charge. Le tableau suivant présente certaines déclarations classiques.
| Élément code | Vue Concepteur de classes |
|---|---|
template <class T>class A {}; |
A<T>Classe de modèle |
template <class T, class U>class A {}; |
A<T, U>Classe de modèle |
template <class T, int i>class A {}; |
A<T, i>Classe de modèle |
template <class T, template <class K> class U>class A {}; |
A<T, U>Classe de modèle |
Le tableau suivant présente quelques exemples de spécialisation partielle.
| Élément code | Vue du Concepteur de classes |
|---|---|
template<class T, class U>class A {}; |
A<T, U>Classe de modèle |
template<class T>class A<T, T> {}; |
A<T, T>Classe de modèle |
template <class T>class A<T, int> {}; |
A<T, int>Classe de modèle |
template <class T1, class T2>class A<T1*, T2*> {}; |
A<T1*, T2*>Classe de modèle |
Le tableau suivant présente quelques exemples d’héritage dans la spécialisation partielle.
| Élément code | Vue Concepteur de classes |
|---|---|
template <class T, class U>class A {};template <class TC>class A<T, int> {};class B : A<int, float>{};class C : A<int, int>{}; |
A<T, U>Classe de modèle Bclasse (points à la classe A) Cclasse (points à la classe A) |
Le tableau suivant présente quelques exemples de fonctions de modèle de spécialisation partielle.
| Élément code | Vue concepteur de classes |
|---|---|
class A{template <class T, class U>void func(T a, U b);template <class T>void func(T a, int b);}; |
Afunc<T, U> (+ 1 surcharge) |
template <class T1>class A {template <class T2>class B {};};template<> template<>class A<type>::B<type> {}; |
A<T1>Classe de modèle B<T2>Classe de modèle (B est contenu dans la classe A sous Types imbriqués) |
template <class T>class C {};class A : C<int> {}; |
Aclasse -> C<int> C<T>Classe de modèle |
Le tableau suivant présente quelques exemples d’héritage de modèle.
| Élément code | Vue Concepteur de classes |
|---|---|
template <class T>class C {};template<>class C<int> {class B {};}class A : C<int>::B {}; |
Aclasse ->B C<int>classe (B est contenu dans la classe C sous Types imbriqués) C<T>Classe de modèle |
Le tableau suivant présente quelques exemples de connexion canonique de classe spécialisée.
| Élément code | Vue du Concepteur de classes |
|---|---|
template <class T>class C {};template<>class C<int> {};class A : C<int> {};class D : C<float> {}; |
Aclasse ->C<int> C<int>classe C<T>Classe de modèle Dclasse ->C<float> |
class B {template <class T>T min (const T &a, const T &b);}; |
Bmin <T> |
Énumérations C++ dans le Concepteur de classes
Concepteur de classes prend en charge les types C++ enum et les types à portée limitée enum class. Voici un exemple :
enum CardSuit {
Diamonds = 1,
Hearts = 2,
Clubs = 3,
Spades = 4
};
// or...
enum class CardSuit {
Diamonds = 1,
Hearts = 2,
Clubs = 3,
Spades = 4
};
Une forme d’énumération C++ dans un diagramme de classes ressemble à une forme de structure, sauf que l’étiquette lit enum ou classe Enum, il est rose au lieu du bleu, et il a une bordure colorée sur les marges gauche et supérieure. Les formes d’énumération et les formes de structure ont des angles carrés.
Pour plus d’informations sur l’utilisation du enum type, consultez Énumérations.
Typedefs C++ dans le Concepteur de classes
Les instructions Typedef créent une ou plusieurs couches d’indirection entre un nom et son type sous-jacent.
Le Concepteur de classes prend en charge les types typedef C++, qui sont déclarés avec le mot clé typedef, par exemple :
typedef class coord
{
void P(x,y);
unsigned x;
unsigned y;
} COORD;
Vous pouvez ensuite utiliser ce type pour déclarer une instance :
COORD OriginPoint;
Formes de classes et structures
Dans le Concepteur de classes, un typedef C++ a la forme du type spécifié dans le typedef. Si la source déclare typedef class, la forme a des angles arrondis et l’étiquette Classe. Pour typedef struct, la forme a des angles carrés et le label Struct.
Les classes et les structures peuvent avoir des typedefs imbriqués déclarés en leur sein. Dans le Concepteur de classes, les formes de classe et de structure peuvent afficher des déclarations typedef imbriquées en tant que formes imbriquées.
Les formes Typedef prennent en charge les commandes Show as Association et Show as Collection Association dans le menu contextuel.
Exemple de typedef de classe
class B {};
typedef B MyB;
Exemple de définition de type struct
typedef struct mystructtag
{
int i;
double f;
} mystruct;
Typedefs sans nom
Bien que vous puissiez déclarer un typedef sans nom, le Concepteur de classes n’utilise pas le nom de balise que vous spécifiez. Le Concepteur de classes utilise le nom généré par l’affichage de classes . Par exemple, la déclaration suivante est valide, mais elle apparaît dans la vue de classe et le Concepteur de classes en tant qu’objet nommé __unnamed :
typedef class coord
{
void P(x,y);
unsigned x;
unsigned y;
};
Note
Le Concepteur de classes n’affiche pas les typesdefs dont le type source est un pointeur de fonction.
En savoir plus sur les limitations des éléments de code C++
Lorsqu’un projet C++ est chargé, le Concepteur de classes fonctionne de manière en lecture seule. Vous pouvez modifier le diagramme de classes, mais vous ne pouvez pas enregistrer les modifications du diagramme de classes vers le code source.
Le Concepteur de classes prend uniquement en charge la sémantique C++ native. Pour les projets C++ compilés en code managé, le Concepteur de classes visualise uniquement les éléments de code qui sont des types natifs. Par conséquent, vous pouvez ajouter un diagramme de classes à un projet, mais le Concepteur de classes ne vous permet pas de visualiser les éléments dans lesquels la
IsManagedpropriété est définietrue(c’est-à-dire, les types valeur et les types de référence).Pour les projets C++, le Concepteur de classes lit uniquement la définition du type. Par exemple, supposons que vous définissez un type dans un fichier d’en-tête (.h) et définissez ses membres dans un fichier d’implémentation (.cpp). Si vous appelez « Afficher le diagramme de classes » dans le fichier d’implémentation (.cpp), le Concepteur de classes n’affiche rien. Comme autre exemple, si vous appelez « Afficher le diagramme de classes » sur un fichier .cpp qui utilise une
#includeinstruction pour inclure d’autres fichiers, mais ne contient aucune définition de classe réelle, le Concepteur de classes n’affiche à nouveau rien.Les fichiers IDL (.idl), qui définissent des interfaces COM et des bibliothèques de types, ne s’affichent pas dans les diagrammes, sauf s’ils sont compilés en code C++ natif.
Le Concepteur de classes ne prend pas en charge les fonctions et variables globales.
Le Concepteur de classes ne prend pas en charge les unions. Il s’agit d’un type spécial de classe dans lequel la mémoire allouée n’est que la quantité nécessaire pour le membre de données le plus grand de l’union.
Le Concepteur de classes n’affiche pas les types de données de base tels que
intetchar.Le Concepteur de classes n’affiche pas les types définis en dehors du projet actuel si le projet n’a pas de références correctes à ces types.
Le Concepteur de classes peut afficher des types imbriqués, mais pas les relations entre un type imbriqué et d’autres types.
Le Concepteur de classes ne peut pas afficher les types qui sont void ou qui dérivent d’un type void.
Résoudre les problèmes de résolution des types et d’affichage
Emplacement des fichiers sources
Le Concepteur de classes ne suit pas l’emplacement des fichiers sources. Par conséquent, si vous modifiez votre structure de projet ou déplacez des fichiers sources dans votre projet, le Concepteur de classes peut perdre le suivi du type (en particulier le type source d’un typedef, des classes de base ou des types d’association). Vous pouvez recevoir une erreur telle que le Concepteur de classes ne peut pas afficher ce type. Si vous le faites, faites glisser le code source modifié ou déplacé vers le diagramme de classes à nouveau pour le réafficher.
Problèmes de mise à jour et de performances
Pour les projets C++, l'apparition d'une modification du fichier source dans le diagramme de classe peut prendre de 30 à 60 secondes. Ce délai peut également provoquer la génération de l'erreur Aucun type trouvé dans la sélection. Si vous recevez une erreur telle que celle-ci, cliquez sur Annuler dans le message d’erreur et attendez que l’élément de code apparaisse en mode Classe. Une fois cette opération terminée, le Concepteur de classes doit être en mesure d’afficher le type.
Si un diagramme de classes ne se met pas à jour avec les modifications que vous avez apportées dans le code, vous devrez peut-être fermer le diagramme et l’ouvrir à nouveau.
Problèmes de résolution de type
Le Concepteur de classes peut ne pas être en mesure de résoudre les types pour les raisons suivantes :
Le type se trouve dans un projet ou un assembly qui n’est pas référencé à partir du projet qui contient le diagramme de classes. Pour corriger cette erreur, ajoutez une référence au projet ou à l’assembly qui contient le type. Pour plus d’informations, consultez Gestion des références dans un projet.
Le type n’est pas dans l’étendue correcte. Par conséquent, le Concepteur de classes ne peut pas le localiser. Vérifiez que le code ne manque pas de l'instruction
using,imports, ou#include. Vérifiez également que vous n’avez pas déplacé le type (ou un type associé) hors de l’espace de noms dans lequel il était initialement situé.Le type n’existe pas (ou a déjà été commenté). Pour corriger cette erreur, assurez-vous que vous n’avez pas commenté ou supprimé le type de données.
Le type se trouve dans une bibliothèque référencée par une directive #import. Une solution de contournement possible consiste à ajouter manuellement le code généré (fichier .tlh) à une directive #include dans le fichier d’en-tête.
Vérifiez que le Concepteur de classes prend en charge le type que vous avez entré. Consultez Limitations pour les éléments de code C++.
L’erreur que vous voyez probablement pour un problème de résolution de type est que le code est introuvable pour une ou plusieurs formes dans le diagramme de classes '<element>'. Ce message d’erreur n’indique pas nécessairement que votre code est en erreur. Il indique uniquement que le concepteur de classes n’a pas pu afficher votre code. Essayez les mesures suivantes :
Vérifiez que le type existe. Vérifiez que vous n’avez pas involontairement commenté ou supprimé le code source.
Essayez de résoudre le type. Le type peut se trouver dans un projet ou un assembly qui n’est pas référencé à partir du projet qui contient le diagramme de classes. Pour corriger cette erreur, ajoutez une référence au projet ou à l’assembly qui contient le type. Pour plus d’informations, consultez Gestion des références dans un projet.
Vérifiez que le type se trouve dans l’étendue correcte afin que le Concepteur de classes puisse le localiser. Assurez-vous que le code ne manque pas une instruction
using,imports, ou#include. Vérifiez également que vous n’avez pas déplacé le type (ou un type associé) hors de l’espace de noms dans lequel il était initialement situé.
Conseil / Astuce
Pour plus d’informations sur la résolution des problèmes, consultez les erreurs du Concepteur de classes.