Portail / Sujets autour de la programmation / Programmation C/C++ sous Linux / Serveur d'application avec Qt 6 / Concepts généraux(Sommaire)

Un dictionnaire pour stocker des données quelconques.

Mise à jour du 25/05/2024.

Nous avons vu qu'avec la classe IData nous pouvons stocker des données quelconques. Le stockage dans une liste n'est pas très pratique et suppose que chaque objet puisse s'identifier (classe et état) auprès du demandeur.

Il est plus simple de les identifier au moyen d'une clef qui sera "parlante" pour le développeur. Cette clef peut être une chaîne de caractères à laquelle on associe l'objet à conserver. Une liste constituée d'entrées sous forme d'un couple (clef, valeur) est appelée map en anglais ce que nous traduirons ici par "dictionnaire", terme plus proche de sa fonction dans notre langue.

Si on se réfère à la présentation de la réalisation du serveur d'application, Nous aurons au moins 3 niveaux de stockage d'un dictionnaire :

  1. Un pour les données globales intégrant notamment les données de la configuration du serveur ;
  2. Un pour les données propres à l'application ;
  3. Un par session pour y stocker les données qui lui sont propres.

On intuite que la plupart des données de session seront assez fortement couplées aux pages web émises et donc aux services qui les produisent. Il peut être intéressant, mais ce n'est en aucun cas une obligation, de regrouper les données de session par service. C'est pourquoi au lieu d'associer à une clef un seul objet, nous laissons la possibilité d'y associer une liste d'objets quelconques (dérivés de la classe IData).

Principe.

Comme nous utilisons Qt, nous disposons d'une classe patron dédiée à la gestion des dictionnaires : la classe QMap. Nous disposons aussi d'un classe patron dédiée à la gestion des listes : QList. L'attribut principal de cette classe est _spData de classe shared_ptr<QMap<QString,QList<shared_ptr<IData>>>>. Nous avons vu pourquoi nous instancions les données au moyen d'un pointeur intelligent. On peut se poser la qestion de l'intérêt de placer la clef et la liste elle-même dans un pointeur intelligent. Que se passe-t-il si nous ajoutons au dictionnaire une entrée dont clef et liste sont créées par une méthode ? Sont-ils détruits au sortir de la méthode puisqu'ils sont créés sur le tas ? Dans l'affirmative, cette destruction impacte-t-elle celle des objets placés dans le dictionnaire ? La difficulté de C++ est de devoir souvent se poser ce genre de questions.

En fait quand vous ajoutez une clef et sa liste à notre attribut _spData instancié sur la pile, C++ met en oeuvre le mécanisme dit du "constructeur de recopie" pour la clef comme pour la liste. Cela revient à dire qu'un nouvel objet clef, identique à la clef transmise est créé dans la pile et enregistrée au sein du dictionnaire. Si vous modifiez le contenu de la clef par la suite, sans la mettre à jour dans le dictionnaire, se sera bien la clef tranmise par recopie au dictionnaire qui sera conservée et les deux clefs seront donc différentes. Vous pouvez vérfier dans le prototype proposé que la modification de la clef après son enregistrement dans le dictionnaire ne la modifie pas dans ce dernier : c'est bien la preuve que la clef dans le dictionnaire et celle qui lui a été transmise ne sont pas les mêmes objets. Il se passe la même chose pour la liste. Pour vous aidez à appréhender le fonctionement des pointeurs intelligents, nous affichons lors de la présentation de chaque donnée de la liste la valeur du compteur de référencement interne du pointeur. Sa valeur est de 3 : 1 lors de la création, 1 lors de l'ajout à la liste et 1 lors de son référencement pour affichage.

Prototype de mise en oeuvre.

Le prototype proposé reprend les classes DataString et DataLong qui représentent les classes des objets quelconques à enregistrer. Le programme principal créé un dictionnaire d'un nombre aléatoire d'entrées. Chaque entrée est une clef compotrant une valeur numérique générée aléatoirement. Chque donnée de la liste associée à cette entrée est soit un objet de classe DataString soit un objet de classe DataLong. Le choix de cette classe est lui-même aléatoire. L'objet DataString ou DataLong a un état lui-même défini aléatoirement.

Après chaque enregistrement de clef par la fonction addEntry(), la clef est modifiée pour s'assurer de la non répercussion de cette modification sur le dictionnaire.

La documentationcomportant l'ensemble des sources du prototype est gracieusement disponible.

Une fois le dictionnaire principal créé, le programme principal l'affiche en indiquant pour chaque donnée la valeur du compteur de références du pointeur intelligent qui la gère. Voici un exemple d'affichage :

Taille du dictionnaire : 6


Clef N° -5037169139546424887
    ¤ Test 4126956560021035805, compteur smart pointeur3
    * 8754554536848496004, compteur smart pointeur3
    ¤ Test 368101590469937042, compteur smart pointeur3
    ¤ Test 1924135161316147156, compteur smart pointeur3
    ¤ Test 7825714257861366711, compteur smart pointeur3
    * 5717843792526363922, compteur smart pointeur3
    * -8390016301118541542, compteur smart pointeur3
    ¤ Test 6725628491645561940, compteur smart pointeur3

Clef N° -5615573234994717082
    ¤ Test 144611925455001526, compteur smart pointeur3
    ¤ Test 6882610202680333933, compteur smart pointeur3
    ¤ Test 3208955670263230715, compteur smart pointeur3
    * 1602517878976825846, compteur smart pointeur3
    * 324452179963626765, compteur smart pointeur3
    * 6310941080808858834, compteur smart pointeur3
    * -3475877359673505207, compteur smart pointeur3

Clef N° 3994092854067955778
    * 4839754475985537739, compteur smart pointeur3
    * 6409311137637453926, compteur smart pointeur3
    ¤ Test 3190982312750249394, compteur smart pointeur3
    * 6301409924060612973, compteur smart pointeur3
    ¤ Test -8167796565559391312, compteur smart pointeur3

Clef N° 4518937380927017937
    ¤ Test -8758568313196629896, compteur smart pointeur3
    * -3009643826515275147, compteur smart pointeur3
    * 1725071858388971280, compteur smart pointeur3
    ¤ Test 3741242828832627819, compteur smart pointeur3
    * -3217929641838517735, compteur smart pointeur3
    ¤ Test -4580667896146984936, compteur smart pointeur3
    ¤ Test 4864129792595426140, compteur smart pointeur3
    * 2914035447450302392, compteur smart pointeur3
    ¤ Test 4651226910276570512, compteur smart pointeur3

Clef N° 8237442960772794112
    * 588330920631635135, compteur smart pointeur3
    * -4962055141177640498, compteur smart pointeur3

Clef N° 8272824985916890247
    * -2934200263317496948, compteur smart pointeur3

Rédaction par Jean-Marie Piatte (1983-2021)