Comment empécher l'allocation dynamique d'un objet en C++
Technique trouvée sur un blog consacré à l'informatique : on ne fait pas de la magie.
Pour interdire l'allocation dynamique d'un objet, il suffit de définir un opérateur new() comme ci-dessous pour la classe de l'objet.
class maClasse { public: void *operator new (size_t taille) { throw 0; return new int; // peut renvoyer n'importe quoi : on ne passera jamais ici } };
Mais quel est l'intérêt d'interdire ainsi l'allocation dynamique ?
Un objet d'une telle classe ne pourrait qu'être alloué dans la pile :
C'est un moyen de forcer l'utilisation de la technique d'acquisition de ressources par initialisation.
Prenons l'exemple d'un protection d'un code contre l'utilisation simultanée par plusieurs processus. Sous Unix, on peut utiliser des sémaphores, ressources système, pour faire une telle mutuelle exclusion. Supposons que l'utilisation des sémaphores, dans ce cas, soit encapsulée, dans le respect de l'acquisition de ressources par initialisation, dans la classe MUTEX.
Pour protéger une section de code code on écrirait :
Évidemment dans ce cas là, on veut éviter l'allocation d'un objet de type MUTEX par l'opérateur new() qui échappant à la libération automatique pourrait bloquer le système.
Bref, en empêchant l'allocation dynamique, on force la bonne utilisation du C++, ce qui peut être utile vis à vis de programmeurs qui auraient pris de mauvaises habitudes en JAVA.
maClasse objet; // OK maClasse *pointeur = new maClasse(); // produit une exception.
C'est un moyen de forcer l'utilisation de la technique d'acquisition de ressources par initialisation.
Prenons l'exemple d'un protection d'un code contre l'utilisation simultanée par plusieurs processus. Sous Unix, on peut utiliser des sémaphores, ressources système, pour faire une telle mutuelle exclusion. Supposons que l'utilisation des sémaphores, dans ce cas, soit encapsulée, dans le respect de l'acquisition de ressources par initialisation, dans la classe MUTEX.
Pour protéger une section de code code on écrirait :
{ MUTEX mux("mymux.mux"); // acquisition d'une sémaphore UNIX ... code critique (protégé contre un accès simultané)... } // libération automatique
Évidemment dans ce cas là, on veut éviter l'allocation d'un objet de type MUTEX par l'opérateur new() qui échappant à la libération automatique pourrait bloquer le système.
Bref, en empêchant l'allocation dynamique, on force la bonne utilisation du C++, ce qui peut être utile vis à vis de programmeurs qui auraient pris de mauvaises habitudes en JAVA.
Commentaires
Afficher les commentaires en Vue non groupée | Vue groupée
ZeGuigui sur :
Mais bon je suis certain qu'on peut trouver d'autres usages intéressants à cette méthode... le tout étant qu'on sache que c'est possible !
Sébastien sur :
Par ailleurs, pour la protection de code, la méthode native implémentée par Java ne marche qu'en JAVA et ne permet par de communiquer avec des processus non-JAVA ou des processus JAVA hébergés par un autre machine virtuelle. Elle fait appel à un multitâche basé sur des threads et non pas sur le système.
Il existe en JAVA une implémentation des sémaphores système. Quand j'avais cherché , il y a quelques années, une telle fonctionalité, j'étais même tombé sur 5 ou 6 implémentations dont l'avenir n'était pas très clair (cas classique lorsqu'on sort des fonctionalités implémentées par Sun). Elles souffraient évidemment toutes du problème évoqué dans l'article : si on oublie de libérer on bloque tout. Il faut systématiquement faire des try finally en JAVA car il n'existe pas de mécanisme de nettoyage automatique basé sur les destructeurs comme en C++.