Maison >développement back-end >C++ >Pourquoi l'appel d'une fonction membre non virtuelle sur un pointeur nul en C fonctionne-t-il parfois ?

Pourquoi l'appel d'une fonction membre non virtuelle sur un pointeur nul en C fonctionne-t-il parfois ?

DDD
DDDoriginal
2024-12-13 16:58:10660parcourir

Why Does Calling a Non-Virtual Member Function on a Null Pointer in C   Sometimes Work?

Gotcha en C : accéder aux membres de classe non virtuels sur un pointeur nul

En C, appeler des fonctions de membres non virtuels sur un pointeur nul le pointeur peut fonctionner de manière inattendue, posant un curieux casse-tête. Examinons ce comportement à travers un extrait de code intrigant :

class Foo {
public:
    virtual void say_virtual_hi() {
        std::cout << "Virtual Hi";
    }

    void say_hi() {
        std::cout << "Hi";
    }
};

int main() {
    Foo* foo = 0;
    foo->say_hi(); // Works well
    foo->say_virtual_hi(); // Crashes the app
    return 0;
}

Puzzle expliqué

La confusion vient des différents mécanismes utilisés pour appeler des méthodes virtuelles et non virtuelles. .

  • Méthodes virtuelles : Exiger Recherche de table vtable pour déterminer la fonction à appeler, qui échoue pour les pointeurs nuls car aucun objet valide ne leur est associé.
  • Méthodes non virtuelles : Sont compilées directement en tant qu'appel de fonction avec le ce pointeur (référence d'objet) passé en paramètre caché.

Dans le code donné, la méthode non virtuelle say_hi() ne déréférence jamais explicitement le this pointeur, contournant l’erreur de déréférencement du pointeur nul. C'est essentiellement l'équivalent d'un appel de fonction avec un paramètre passé par valeur :

void Foo_say_hi(Foo* this);

Foo_say_hi(foo);

Comportement non défini

Techniquement, appeler n'importe quelle fonction (même non virtuelle) sur un pointeur nul est un comportement indéfini en C . Cependant, certaines implémentations du compilateur peuvent fournir un comportement bien défini pour des scénarios spécifiques, tels que l'appel de fonction non virtuelle ci-dessus.

Attention

Bien que le comportement inattendu puisse sembler pratique, s’y fier est risqué et n’est pas une bonne pratique. Évitez toujours d'accéder aux membres de la classe sur des pointeurs nuls, car cela peut conduire à des résultats inattendus et imprévisibles.

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