le terme handle est utilisé pour désigner n'importe quelle technique qui permet de manipuler un autre objet (un genre de pseudo pointeur
généralisé). Ce terme est (volontairement) ambigu et peu précis.
L'ambiguïté est un avantage dans certains cas. Par exemple, au tout début du design vous ne serez peut-être pas prêt à adopter
une représentation spécifique pour désigner les handles. Vous ne serez peut-être pas sûr du choix à faire entre les simples pointeurs,
les références, les pointeurs de pointeurs, les références de pointeurs, ou encore des tableaux indicés, ou des tables de hachage, ou des
bases de données ou n'importe quelle autre technique. Si vous savez que vous aurez besoin de quelque chose qui identifiera de façon unique
un objet, appelez cette chose un handle.
Si votre but final est de permettre à
une portion de code d'identifier/rechercher un objet spécifique d'une
classe d'un certain type (par ex.
Fred), vous devrez passer un handle sur Fred à cette portion de code. Le handle peut être une chaîne qui peut-être utilisée comme une clé
dans une table de recherche bien connue. Par exemple, une clé dans
std:: map< std:: string,Fred>
|
ou
std:: map< std:: string,Fred* >
|
ou encore un entier qui sera un indice dans un tableau du genre
Fred* array = new Fred[maxNumFreds]
|
ou tout simplement un pointeur sur Fred, ou n'importe quoi d'autre.
Les débutants pensent souvent en termes de pointeurs, mais en réalité, ils prennent un risque. Que se passe-t-il si l'objet Fred doit
être déplacé ? Comment savoir quand il est sans risque d'effacer l'objet Fred ? Que se passe-t-il si l'objet doit être sérialisé ? ....
La plupart du temps, on aura tendance à ajouter de plus en plus de couches d'indirections pour gérer ces cas de figure. Par exemple, le
handle sur Fred devrait être un Fred**, où le pointeur pointant sur Fred* est supposé ne jamais être déplacé, mais à un moment
le pointeur doit être déplacé, on met seulement à jour le pointeur sur Fred*. Ou vous décidez que le handle devient un entier désignant
l'objet Fred dans une table, etc.....
Le fait est que nous utilisons le mot handle tant que nous ne savons pas le détail de ce que nous allons faire.
Une autre circonstance dans laquelle nous utilisons le mot handle est quand on préfère rester vague au sujet de ce que nous avons
déjà fait (on utilise parfois le terme 'cookie' pour
cela, par ex. "Le programme passe un cookie qui est utilisé pour identifier de façon
unique l'objet Fred adéquat"). La raison pour laquelle nous voulons (parfois) rester vague est de minimiser les effets de bord si les
détails d'implémentations devaient changer. Par exemple, si quelqu'un change le handle qui était une chaîne qui servait à faire une
recherche dans une liste de hachage en un entier qui sert à indicer une table, cela pourrait causer le changement de dizaines de milliers
de lignes de code.
Pour faciliter la maintenance quand les détails de représentation d'un handle changent (ou tout simplement pour rendre le code plus
lisible), nous encapsulerons le handle dans une classe. Cette classe surchargera souvent les opérateurs -> et * (comme le handle
agit comme un pointeur, il semble logique qu'il ressemble à un pointeur).
|