Classes imbriquées en C++
Cet article explique comment fonctionnent les classes et structures imbriquées en C++.
Définir un objet class
ou struct
dans une autre classe en C++
Parfois, nos classes ont besoin de types de données dits auxiliaires, généralement définis comme des objets struct
ou class
personnalisés. Ces classes auxiliaires peuvent être définies dans les autres classes, et dans de tels cas, elles seront appelées types imbriqués ou classes imbriquées. Ce dernier concept offre de nombreux avantages pour le programmeur, comme de bonnes limites de portée et un contrôle d’accès.
L’exemple suivant illustre un scénario simple dans lequel nous pourrions définir une classe imbriquée. La classe principale - CircularList
implémente une liste chaînée circulaire et doit définir un nœud de type composite, nommé - ListNode
. Dans ce cas, ce dernier est défini en portée globale à l’aide du mot clé struct
. Ainsi, ses membres sont accessibles publiquement par d’autres classes.
#include <iostream>
#include <string>
using std::string;
struct ListNode {
struct ListNode *next = nullptr;
string data;
} typedef ListNode;
class CircularList {
public:
explicit CircularList(string data) {
head = new ListNode;
head->next = head;
head->data = std::move(data);
end = head;
};
ListNode *insertNodeEnd(string data);
ListNode *insertNodeHead(string data);
void printNodes();
~CircularList();
private:
ListNode *head = nullptr;
ListNode *end = nullptr;
};
int main() { return EXIT_SUCCESS; }
Alternativement, nous pouvons déplacer la définition ListNode
dans la classe CircularList
. ListNode
n’est pas accessible dans l’espace de noms global, nous devons donc inclure l’espace de noms CircularList::
avant les noms de classes imbriqués. De plus, il est important de savoir quel spécificateur d’accès la classe imbriquée possède, car les règles de contrôle d’accès habituelles s’y appliquent également.
Dans ce cas, ListNode
est défini comme une classe membre publique, et par conséquent, il est accessible à partir de la fonction main
en utilisant la notation CircularList::ListNode
. Si une classe imbriquée est définie comme un membre protégé
, elle est accessible en englobant la classe, les classes amies de cette dernière et les classes dérivées. D’un autre côté, un spécificateur private
pour une classe imbriquée signifierait qu’elle n’est accessible qu’au sein de la classe englobante et des classes d’amis.
#include <iostream>
#include <string>
using std::string;
class CircularList {
public:
// Helper Types ->
struct ListNode {
struct ListNode *next = nullptr;
string data;
} typedef ListNode;
// Member Functions ->
explicit CircularList(string data) {
head = new ListNode;
head->next = head;
head->data = std::move(data);
end = head;
};
ListNode *insertNodeEnd(string data);
ListNode *insertNodeHead(string data);
void printNodes();
~CircularList();
private:
ListNode *head = nullptr;
ListNode *end = nullptr;
};
int main() {
// ListNode *n1; // Error
CircularList::ListNode *n2;
return EXIT_SUCCESS;
}
Généralement, une classe imbriquée peut avoir des spécificateurs d’accès habituels pour ses membres, et les règles s’appliqueront à la classe englobante de manière régulière. Pendant ce temps, une classe imbriquée ne bénéficie d’aucun accès spécial aux membres de la classe englobante.
Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.
LinkedIn Facebook