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 :

operator delete privé


Sujet :

C++

  1. #1
    Membre émérite Avatar de MatRem
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    750
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 750
    Par défaut operator delete privé
    Bonjour,

    Pourquoi ceci ne compile pas (au moins sous gcc 4 et vs2005) ? :

    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
    struct S
    {
    	S() {}
    };
     
    class C
    {
    	void operator delete(void *) {} //line 8
    	S s;
    };
     
    int main()
    {
    	new C; //line 15
    }
    D'après le message d'erreur, l'operator delete semble avoir besoin d'être appelé... mais pourquoi ?
    De plus si j'enlève le constucteur de S, il n'y a plus de problème.

  2. #2
    Membre Expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Par défaut
    Sacré colle O__O


    Ce qui est fou c'est qu'il suffit de commenter le membre S de C pour que ça compile... là je vois pas trop le rapport mais j'imagine qu'il y a une manip dans le constructeur qui utilise l'operateur delete....???

  3. #3
    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
    C'est quoi les messages d'erreur ?
    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
    .

  4. #4
    Membre Expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Par défaut
    L'erreur c'est que l'operateur delete est inaccessible. (VS2008)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    1>Compiling...
    1>MAin.cpp
    1>e:\tests\test_delete\test_delete\main.cpp(19) : error C2248: 'C::operator delete' : cannot access private member declared in class 'C'
    1>        e:\tests\test_delete\test_delete\main.cpp(13) : see declaration of 'C::operator delete'
    1>        e:\tests\test_delete\test_delete\main.cpp(7) : see declaration of 'C'
    Le plus étrange c'est que la ligne pointée par l'erreur est la ligne du new...d'où mon test de virer le membre voir.

  5. #5
    Membre très actif
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    432
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 432
    Par défaut
    Ca viendrai pas du fait que l'operator delete est private ?
    Tu devrais peut-être mettre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    public :
        void operator delete(void *) {}

  6. #6
    Membre émérite Avatar de MatRem
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    750
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 750
    Par défaut
    Effectivement cela résoud le problème, mais ne l'explique pas

    En plus j'ai besoin que l'opérateur delete soit privé.

    Sous gcc 4.2.3 les messages sont équivalents :
    g++ -O0 -g3 -pedantic -pedantic-errors -Wall -Werror -c -std=c++98 -Wextra -MMD -MP -MF"main.d" -MT"main.d" -o"main.o" "../main.cpp"
    ../main.cpp: In function 'int main()':
    ../main.cpp:8: error: 'static void C::operator delete(void*)' is private
    ../main.cpp:15: error: within this context
    ../main.cpp:8: error: 'static void C::operator delete(void*)' is private
    ../main.cpp:15: error: within this context

  7. #7
    Membre Expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Par défaut
    Est-ce que par hasard il est dit dans le standard que si l'objet a des membres il doit avoir un operateur delete publique? C'est vraiment super bizarre...
    Je comprends pas le rapport entre le membre, le constructeur et le delete, mais ya forcément un rapport...

  8. #8
    Membre très actif
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    432
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 432
    Par défaut
    Heu, à quoi ça peut te servir un operator delete privé .

    Et puis sur le :
    Y a pas comme un problème ?
    Là tu crée un objet C n'importe où dans la mémoire sans récupéré l'adresse.
    D'habite on fait plutôt :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    C *pC;
     
    pC = new C;

  9. #9
    Membre Expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Par défaut
    C'est tout a fait valide de faire le new dans le vent, simplement la mémoire est perdue.

    D'ailleurs la première chose que j'ai vérifié c'est que l'erreur est toujours là si tu met un pointeur tel que tu l'écris.

    Le problème ne viens pas de là.

    Le problème c'est que a part si ya une subtilitée de fourbe OU un problème du a la façon du compilateur de lire le code, le code en exemple est bien valide : même si tu déclares un operateur delete en privé, tant qu'il est pas appelé par du code quelque part, le compilateur ne peut pas le détecter!

    Surtout que là l'erreur ne survient QUE si la classe en question possede un membre...

    O___O;


    Ya forcément du code généré sans qu'on le veuille mais c'est encore plus bizarre que le problème soit le même sous gcc ET sous VS...

  10. #10
    Alp
    Alp est déconnecté
    Expert confirmé

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Par défaut
    Si le problème survient sous gcc + vc++, c'est peut-être que le standard interdit une telle chose.

    Quelqu'un peut regarder la norme ?

    J'ai hâte de savoir pourquoi ils n'en veulent pas. Peut-être qu'un gourou pourra nous expliquer ça

  11. #11
    Membre expérimenté
    Profil pro
    Inscrit en
    Août 2007
    Messages
    190
    Détails du profil
    Informations personnelles :
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Août 2007
    Messages : 190
    Par défaut
    Je ne suis pas un gourou mais je vais quand même tenter une explication.
    Dans le standard il est dit :
    If the new-expression creates an object or an array of objects of class type, access and ambiguity control are
    done for the allocation function, the deallocation function (12.5), and the constructor (12.1). If the new
    expression creates an array of objects of class type, access and ambiguity control are done for the destructor
    (12.4).
    et également :
    If the new-expression begins with a unary :: operator, the deallocation function’s name is looked up in the
    global scope. Otherwise, if the allocated type is a class type T or an array thereof, the deallocation
    function’s name is looked up in the scope of T. If this lookup fails to find the name, or if the allocated type
    is not a class type or array thereof, the deallocation function’s name is looked up in the global scope.

  12. #12
    Membre émérite Avatar de MatRem
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    750
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 750
    Par défaut
    Cela parait intéressant, mais que veulent dire exactement :

    access and ambiguity control are done
    et
    is looked up
    Si cela veut dire que l'operator delete doit être accessible au niveau de la new expression, outre le fait que je n'en vois pas l'intérêt, je ne commprends pas pourquoi le fait de ne pas définir l'opérateur par défaut de T, ne pose plus le problème de compilation.

  13. #13
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 394
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 394
    Par défaut
    Je crois que c'est au cas où le constructeur lancerait une exception.

    Ce doit être pour la même raison que si l'on définit un opérateur new spécial dans une classe, il faut définir un opérateur delete avec une signature similaire (si on ne le fait pas, Visual donne un message d'erreur ou un warning disant spécifiquement qu'on a besoin d'un opérateur delete au cas où le constructeur excepterait)
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  14. #14
    Membre émérite Avatar de MatRem
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    750
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 750
    Par défaut
    Effectivement la levée d'exception possible dans le constructeur de T, obligerait l'appel à l'operator delete dans la new exepression. Bien vu

    Par contre la norme semble dire qu'il faut que l'operator delete soit tout le temps accessible depuis la new expression (du moins sur un class type) ?

  15. #15
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    106
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 106
    Par défaut
    Bien vu Médinoc, ton explication parrait logique.
    Et dire que je me suis creuse la tete un bon moment
    On en apprend tous les jours...

  16. #16
    Membre Expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Par défaut
    C'est clair, un sacré puzzle.

  17. #17
    Membre émérite
    Inscrit en
    Juillet 2005
    Messages
    512
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 512
    Par défaut
    Je viens de tester avec gcc si on met conjointement un objet de classe comme donnée membre ça ne compile pas
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class C
    {
         void operator delete(void *) {} 
         string s;
    }
    mais si je met une variable ordinaire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class C
    {
         void operator delete(void *) {} 
         int i;
    }
    ça compile.

    Si je met un constructeur public et aucune donnée membre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class C
    {
       void operator delete(void *) {}
       public:
       C() {}
    };
    ça ne compile plus !


    J'ai testé avec le compilateur Borland il compile tout sans boncher.

  18. #18
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    106
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 106
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    class C
    {
         void operator delete(void *) {} 
         string s;
    }
    Je suppose ici que que le constructeur de "string" qui pourrait eventuellement thrower une exception. Et donc l'operateur delete doit pouvoir etre apelle.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    class C
    {
         void operator delete(void *) {} 
         int i;
    }
    La construction de 'i' ne peut pas generer une exception, donc ca compile.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    class C
    {
       void operator delete(void *) {}
       public:
       C() {}
    };
    La je suppose que le compilateur ne va pas regarder l'interieur du code du constructeur et donc suppose qu'une exception peut thrower.

    Et sinon il fait beau dehors ?? ^^

  19. #19
    Membre émérite Avatar de MatRem
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    750
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 750
    Par défaut
    Effectivement dans les deux cas ou gcc ne veut pas compiler ton code, il pourrait y avoir une levée d'exception dans les constructeurs.

    Par contre le compilateur pourrait être plus malin et regarder la définition du constructeur pour savoir s'il y a réellement un risque d'exception.
    Peut être que le compilateur borland est plus malin justement.
    Que donne la compilation de ce code avec borland ? :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    class C
    {
       void operator delete(void *) {}
       public:
       C() { throw int(0);}
    };
    Cependant si la norme oblige à rendre disponible l'operator delete dans tout les cas (je ne sais toujours pas si c'est le cas), ces compilateurs ne suivent pas le standard.

  20. #20
    Membre émérite
    Inscrit en
    Juillet 2005
    Messages
    512
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 512
    Par défaut
    Peut être que le compilateur borland est plus malin justement.
    Que donne la compilation de ce code avec borland ? :
    Peut-être pas tant que cela, car il compile quand même.

Discussions similaires

  1. [Débutant] Insert, Update, Search and Delete (CRUD operation) with SharePoint 2013 using VS 2012
    Par siffon dans le forum Développement Sharepoint
    Réponses: 2
    Dernier message: 17/02/2014, 12h22
  2. operator new sans delete
    Par babar63 dans le forum C++
    Réponses: 21
    Dernier message: 26/02/2008, 22h33
  3. delete operator
    Par shirya dans le forum C++
    Réponses: 6
    Dernier message: 22/12/2005, 12h44
  4. Réponses: 3
    Dernier message: 23/08/2005, 11h02
  5. Namespace et surcharge operator new/delete
    Par ZeLegolas dans le forum C++
    Réponses: 11
    Dernier message: 26/07/2005, 13h55

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