Tableaux avec objets dérivés : les pièges de la suppression[]
La norme C indique explicitement que la suppression d'un tableau d'objets dérivés à l'aide d'une base le pointeur entraîne un comportement indéfini. Cette règle apparemment ambiguë a soulevé des questions quant à sa justification et ses implications potentielles.
Pour comprendre ce concept, passons en revue la distinction entre les types statiques et dynamiques. Supposons que nous ayons l'extrait de code suivant :
<code class="cpp">struct B { virtual ~B() {} }; struct D : B {}; B* p = new D();</code>
Dans ce cas, le type statique de p est B*, tandis que le type dynamique de *p est D. En effet, p pointe vers un sous-objet de type D qui a été construit à la place d'un objet B.
Cependant, lorsque nous déclarons un tableau à l'aide d'un pointeur de base, une différence subtile apparaît. Considérez ce code :
<code class="cpp">B* p = new D[20];</code>
Ici, p pointe vers le sous-objet de base du premier élément du tableau, pas vers le premier élément lui-même. Par conséquent, l'utilisation de delete [] p viole l'exigence selon laquelle les types statiques et dynamiques du tableau correspondent.
La raison de ce comportement non défini réside dans l'inefficacité et la complexité potentielles qu'il introduirait dans l'environnement d'exécution. Pour supprimer correctement un tableau d'objets dérivés à l'aide d'un pointeur de base, l'implémentation devrait récupérer dynamiquement le type d'élément du tableau et convertir chaque pointeur vers le type correct avant d'effectuer la suppression. Cette surcharge est jugée inutile, surtout compte tenu des cas d'utilisation limités des tableaux polymorphes.
De plus, l'utilisation du pointeur de base pour supprimer le tableau dérivé pose un autre problème. Comme p pointe vers un sous-objet, les accès ultérieurs aux éléments du tableau (par exemple, p[i] pour i > 0) produiraient des résultats incorrects. Cela confirme en outre la restriction interdisant l'utilisation de delete [] avec un pointeur de base pour les tableaux d'objets dérivés.
En conclusion, le comportement non défini de la suppression d'un tableau d'objets dérivés à l'aide d'un pointeur de base découle de la complexité inhérente et du manque d'utilité qu'il introduirait. Bien qu'il soit possible d'implémenter un delete [] spécialisé qui gère ce cas, cela aurait un coût en termes de performances et de convivialité, incompatible avec la philosophie de conception de C.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!