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 :

delete sur un void*


Sujet :

C++

  1. #1
    Membre éclairé Avatar de Biosox
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    298
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 298
    Par défaut delete sur un void*
    Bonjour. Je suis tombé sur un truc louche et j'aimerais votre avis dessus.

    Dans un code que j'observe, j'ai une classe qui a (entre autres) une variable d'instance qui est un void*
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    classe MaClasse
    {
      /*...*/
      void* maVariable;
      /*...*/
    }
    Dans le constructeur de MaClasse, maVariable est initialisée en construisant une instance d'une autre classe bien determinée:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    MaClasse::MaClasse()
    {
      /*...*/
      maVariable = new UneClasseBienDeterminee();
      /*...*/
    }
    Dans chacune des fonctions ou maVariable est utilisee, elle est castée:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    MaClasse::uneFonctionQuelconque
    {
      /*...*/
      ((UneClasseBienDeterminee*)maVariable)->uneFonctionDeLaClasseBienDeterminee();
      /*...*/
    }
    SAUF lors de la destruction (ce qui m'inquiete)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    MaClasse::~MaClasse()
    {
      /*...*/
      delete maVariable; maVariable=NULL;
      /*...*/
    }
    Ma question est: tout ceci est-il bien normal? La "ClasseBienDeterminee" est dans une librarie dont je ne possède pas de version compilée et mode debug. Je ne peux donc pas "stepper" dedans, et je n'ai pas vraiment moyen de savoir si son destructeur est bien appellé ou non.
    Il ne semble pas y avoir d'erreur au run-time, mais comme la destruction se fait au moment de quitter le programme, je pense que même si le destructeur n'est pas appellé je ne m'en apercevrait pas.
    Merci de vos avis

  2. #2
    Membre chevronné

    Inscrit en
    Octobre 2007
    Messages
    234
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 234
    Par défaut
    Ce qui est sûr c'est que le destructeur n'est pas appelé, parce qu'il ne sait pas de quel type il s'agit. Ensuite au niveau de la libération de la mémoire je ne pas dire si elle est effectivement libérée ou pas, de toute façon g++ me mets un warning 'deleting void* is undefined'.
    Ensuite ce que je comprends pas dans le code c'est pourquoi maVariable est void* alors qu'elle est castée partout (sauf au delete) en UneClasseBienDeterminee*, pourquoi pas avoir maVariable en UneClasseBienDeterminee* ?

  3. #3
    Membre chevronné Avatar de fenkys
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    376
    Détails du profil
    Informations personnelles :
    Âge : 58
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Octobre 2007
    Messages : 376
    Par défaut
    void* est un pointeur sur un type indéfini. Pour appeler une fonction membre, il faut donc le caster, puisqu'au moment de la compilation, le type qui sera stocké dedans est inconnu. void* n'a aucune fonction membre du type uneFonctionDeLaClasseBienDeterminee().

    En revanche, delete n'est pas un membre de l'objet et peut être appelé sur n'importe quel type de pointeur. La compilation passe donc bien et c'est à l'execution qu'un problème pourra éventuellement se présenter. Or un pointeur en C++ n'est pas exactement comme un pointeur C. Il contient l'information sur l'adresse mémoire de l'objet mais aussi des infos sur le type de l'objet. Delete est donc tout à fait capable d'appeler le bon destructeur sans casting si la classe a été correctement declarée.

  4. #4
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    Citation Envoyé par kinji1 Voir le message
    Ensuite ce que je comprends pas dans le code c'est pourquoi maVariable est void* alors qu'elle est castée partout (sauf au delete) en UneClasseBienDeterminee*, pourquoi pas avoir maVariable en UneClasseBienDeterminee* ?
    Une fois, je l'ai fais de mettre une variable en void * dans la déclaration de la classe dans le fichier .h et le caster systématiquement lors de son utilisation dans la définition de la classe dans le fichier .cpp et cela avait un but.

    Je construisait une DLL avec une classe exportée dans un fichier .h et je ne voulais pas encombrer le futur utilisateur de cette DLL et de ce .h avec d'autre fichiers à inclure.

    Donc les fichiers nécessaires étaient inclus dans le fichier cpp, je pouvais le compiler dans mon environnement de développement et livrer la DLL ainsi que le fichier .h

    Je suis pas très fier de cela mais c'était pour la bonne cause
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  5. #5
    Membre chevronné Avatar de fenkys
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    376
    Détails du profil
    Informations personnelles :
    Âge : 58
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Octobre 2007
    Messages : 376
    Par défaut
    Une declaration forward de ta classe n'aurait pas été préférérable ?

    Ca fait exactement la même chose que ce que tu cherchais à faire, sauf que tu n'aurais pas declaré ton pointeur void* mais avec le bon type. Résultat, tu ne te serais pas d'avantage encombré avec les includes, et tu aurais évité les typecasting du pointeur, tout en continuant à bénéficier des contrôles de type à la compilation.

  6. #6
    Membre chevronné

    Inscrit en
    Octobre 2007
    Messages
    234
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 234
    Par défaut
    Citation Envoyé par fenkys Voir le message
    Delete est donc tout à fait capable d'appeler le bon destructeur sans casting si la classe a été correctement declarée.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
     
    #include <iostream>
    using namespace std;
     
    class A
    {
    	int id;
    	public:
    	A(int i)
    	{
    		id = i;
    	}
    	~A()
    	{
    		cout << "destructeur de " << id << "\n";
    	}
    }
    ;
     
    int main()
    {
    	A* a = new A(0);
    	delete a;
    	void* b = new A(1);
    	delete b;
    	return 0;
    }
    Sur ce code qui essaie de faire un delete sur b (de type void*) mais qui pointe sur un A, g++ me donne un "warning: deleting 'void*' is undefined" même s'il ne fait pas d'erreur de compilation et à l'exécution le destructeur n'est pas appelé.

  7. #7
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    Citation Envoyé par fenkys Voir le message
    Une declaration forward de ta classe n'aurait pas été préférérable ?
    Oui, maintenant, c'est ce que je ferais, mais à l'époque, je ne savais pas que cela existait. On n'apprend pas le C++ en 3 jours et au début, on fait des erreurs de jeunesse
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  8. #8
    Membre éclairé Avatar de Biosox
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    298
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 298
    Par défaut
    Citation Envoyé par kinji1 Voir le message
    Ensuite ce que je comprends pas dans le code c'est pourquoi maVariable est void* alors qu'elle est castée partout (sauf au delete) en UneClasseBienDeterminee*, pourquoi pas avoir maVariable en UneClasseBienDeterminee* ?
    Ben c'est une question que je me pose justement. Ce code n'est pas de moi, et j'essaie de le comprendre.
    Citation Envoyé par ram_0000 Voir le message
    Une fois, (...) Je construisait une DLL avec une classe exportée dans un fichier .h et je ne voulais pas encombrer le futur utilisateur de cette DLL et de ce .h avec d'autre fichiers à inclure.
    Je suppose que c'est la même raison, car il s'agit effectivement d'une DLL et les includes sont fait dans le cpp.

    En tout cas merci à tous pour vos réponses, elles me sont utiles

  9. #9
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Par défaut
    Citation Envoyé par fenkys Voir le message
    Delete est donc tout à fait capable d'appeler le bon destructeur sans casting si la classe a été correctement declarée.
    C'est faux il ne sera jamais appelé. J'en ai déjà fait l'expérience.

Discussions similaires

  1. [thinking in C++] delete sur void *
    Par exhortae dans le forum C++
    Réponses: 2
    Dernier message: 20/04/2008, 11h59
  2. delete sur plusieurs tables
    Par drinkmilk dans le forum Oracle
    Réponses: 11
    Dernier message: 22/03/2006, 16h43
  3. [VS2005][C#] Delete sur un Dataset typé
    Par Xno dans le forum Windows Forms
    Réponses: 3
    Dernier message: 19/09/2005, 18h13
  4. [Firebird] DELETE sur le résultat d'une requete d'un IBQUERY
    Par shashark dans le forum Bases de données
    Réponses: 3
    Dernier message: 25/06/2005, 18h17
  5. delete sur une vue: rule
    Par Bouboubou dans le forum PostgreSQL
    Réponses: 8
    Dernier message: 18/05/2004, 18h58

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