IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Appel à une fonction virtuelle pure


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Ingénieur validation
    Inscrit en
    Août 2018
    Messages
    42
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur validation
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2018
    Messages : 42
    Par défaut Appel à une fonction virtuelle pure
    Bonjour

    Je vous fais part d'un bug que je pensais, naïvement, impossible à obtenir.
    Terminaison brutale d'un programme avec l'erreur Appel à une fonction virtuelle pure.

    Première réaction d'étonnement : Comment appeler une fonction virtuelle pure d'un objet qu'on a même pas pu instancier ?
    Après analyse, il s'agit bien d'une instance d'objet dérivé et la backtrace m'indique que le problème survient dans le destructeur de la classe mère.

    Là effectivement, c'est plus clair. La couche de la classe dérivée vient d'être détruite et la vtable m'oriente vers une impasse.

    Dans mon cas, il ne s'agissait pas d'un appel explicite à la fonction virtuelle depuis le destructeur. C'eût été trop simple.
    Cette hiérarchie de classes contient des éléments d'IHM et la classe mère possède un conteneur de widgets.
    Or, ces widgets lèvent des événements lorsqu'ils sont sélectionnés, connectés à cette foutue fonction virtuelle.

    Lors de la destruction de la classe mère, la destruction des membres entraîne la destruction du conteneur de widgets… qui entraîne la destruction des widgets un par un.
    Lors de la destruction du widget sélectionné, il y a sélection automatique du widget suivant, levée d'événement, appel de fonction virtuelle pure => Crack Boom.

  2. #2
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 599
    Par défaut
    Bonjour,

    Il y a quelque part un défaut structurel.

    Je comprends le problème comme:
    - l'objet est détruit
    - le destructeur de l'objet est déroulé
    - qui provoque la destruction ou l'appel de fonctions d'autres objets
    - un de ces objets détruit ou utilisé appelle une fonction virtuelle pure de l'objet initial (c'est là l'erreur, accéder à un mort). Et comme l'objet est en cours de destruction, la fonction est devenue pure!
    Si la fonction n'était pas pure on aurait une utilisation d'un objet en cours de destruction (donc encore en mémoire) qui souvent n'a aucun effet visible, la fonction pure ne fait que mettre en évidence un problème latent.

  3. #3
    Membre éclairé
    Homme Profil pro
    Ingénieur validation
    Inscrit en
    Août 2018
    Messages
    42
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur validation
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2018
    Messages : 42
    Par défaut
    Je dois vérifier s'il est vraiment pertinent que la fonction liée à l'événement de sélection d'un widget soit virtuelle.
    Après tout, si c'est la classe mère qui possède les widgets, il y a de fortes chances que les actions à réaliser lors d'une sélection soient suffisamment communes pour être gérées par la classe mère.

    Mais je crains qu'in fine, il y ait un appel à un comportement spécifique à chaque classe dérivée. Ce qui fait que le problème d'appel polymorphique arrivera malgré tout.
    Pour l'instant, j'ai circonscrit le problème en déconnectant les événements avant la destruction.

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    C'est pour ça que les moteurs de jeu, sdk UI etc un peu gros finissent (quasi) tous par avoir des fonction OnPostInit, OnPreDelete etc qui sont appelés directement après le constructeur / avant le destructeur et le constructeur / destructeur ont des exécutions minimales qui génèrent que peu voire pas de side-effects
    OnPreDelete tu déconnectes tout, et dans le destructeur tu réinitialises / nettoies uniquement.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

Discussions similaires

  1. Réponses: 4
    Dernier message: 11/10/2013, 12h08
  2. Réponses: 15
    Dernier message: 07/06/2010, 20h25
  3. Réponses: 2
    Dernier message: 02/10/2008, 16h37
  4. Fonction appelant une fonction virtuelle pure
    Par oodini dans le forum C++
    Réponses: 12
    Dernier message: 19/09/2008, 08h24
  5. Réponses: 2
    Dernier message: 05/03/2006, 19h29

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo