Maison >développement back-end >C++ >Devriez-vous hériter des conteneurs C STL ?

Devriez-vous hériter des conteneurs C STL ?

Barbara Streisand
Barbara Streisandoriginal
2024-12-01 11:58:11937parcourir

Should You Inherit from C   STL Containers?

Le piège potentiel de la dérivation à partir de conteneurs C STL

La pratique consistant à dériver à partir de conteneurs C Standard Library (STL) a fait l'objet de débat, certains s’opposant à son utilisation. Malgré les avantages perçus, tels que la surcharge des fonctions et l'activation de la spécialisation, cette approche présente des risques potentiels.

L'absence de destructeurs virtuels dans les conteneurs STL présente un danger important. Lors de la dérivation d'une classe à partir d'un conteneur STL dépourvu de destructeur virtuel, la classe dérivée peut ne pas être en mesure de gérer correctement le comportement polymorphe. Cela peut conduire à des résultats inattendus, en particulier lorsque les objets de classes dérivées sont stockés dans des conteneurs et accessibles via des pointeurs de classe de base.

Pour illustrer, considérons le scénario suivant :

#include <vector>

void kill_it(std::vector<double> *victim) {
    delete victim; // Invokes non-virtual ~std::vector<>()
}

typedef std::vector<double> Rates;
class Charges: public std::vector<double> { };

int main() {
    std::vector<double> *p1, *p2;
    p1 = new Rates;
    p2 = new Charges;
    
    // Possible error introduced by user code
    kill_it(p2);
    kill_it(p1);
    
    return 0;
}

Dans cet exemple , la fonction kill_it n'a aucune connaissance de la classe dérivée Charges. Par conséquent, il invoquera le destructeur non virtuel de la classe de base std::vector, ce qui peut conduire à un comportement indéfini lors de la destruction d'un objet de type Charges. Ce comportement ne se produirait pas si Charges était implémenté en tant qu'alias de type ou typedef, comme on le voit avec Rates.

Un autre problème potentiel lié à la dérivation à partir de conteneurs STL découle de l'implémentation par Microsoft de la classe vectorielle. Dans cette implémentation, la classe vectorielle elle-même est implémentée par héritage, avec vector<> dérivé publiquement de _Vector_Val<>. Cela ajoute une couche supplémentaire de complexité et de dangers potentiels lorsque vous travaillez avec des classes dérivées.

Bien qu'il puisse y avoir des avantages à utiliser l'héritage dans certains scénarios, les avantages s'accompagnent souvent d'une complexité et de risques potentiels accrus. La composition, utilisant un conteneur comme variable membre plutôt qu'une classe de base, est généralement préférée pour plus de clarté et pour éviter les problèmes potentiels associés à la dérivation.

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn