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

MFC Discussion :

Template & delete


Sujet :

MFC

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : Etats-Unis

    Informations forums :
    Inscription : Juin 2002
    Messages : 256
    Par défaut Template & delete
    Salut !

    J'ai créé une classe template afin de me simplifier certaines opérations.
    Mais un probleme se pose :

    lors que j'ecris un code similaire a ca :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    MyTpl<MyStruct*> *Obj;
    Obj = new MyTpl<MyStruct*>();
     
    Obj->Add(....);
     
    delete Obj;
    aucuns problemes puisque dans le dteur de ma classe MyTpl j'execute l'instruction "delete MyObj" (type : T MyObj);

    Cependant, lorsque j'ecris :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    MyTpl<int> *Obj;
    Obj = new MyTpl<int>();
     
    Obj->Add(...);
     
    delete Obj
    j'ai une erreur compilo qui me dit qu'il ne peut effectuer delete sur un int. C'est tout a fait logique.
    Donc je me demande comment differencier un pointeur, sur lequel on peut donc effectuer "delete, et un type statique, non pointeur.
    Comment faire ?
    merci

  2. #2
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2003
    Messages : 50
    Par défaut


    Est ce qu'un moyen n'est pas de faire dans le 2e cas :

    MyTpl<int *> *Obj;
    Obj = new MyTpl<int *>();

    Obj->Add(...);

    delete Obj

    donc utiliser des int * et non des int, ce qui entraine qu'il faudra allouer les int pour pouvoir s'en servir.

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : Etats-Unis

    Informations forums :
    Inscription : Juin 2002
    Messages : 256
    Par défaut
    Effectivement, je peux faire comme ca... mais comme tu l'as dis, il faut alors allouer des "int*" et bien penser a les detruires, etc...

    bref, c'est beaucoup plus contraignant que d'utiliser des "int". C'est pourquoi j'aimerai pouvoir choisir sans modifier l'architecture de ma classe.

    merci

  4. #4
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Par défaut
    peut etre parce que tu drevais declarer ton tpl de cette maniere:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    template<class TYPE>
    class CMyTpl : public CObject
    {
    	CMyTpl(){};
    };
    CMyTpl<int> *pTpl=NULL;
    etc ... et donc dans type tu mets ce que tu veux ..

  5. #5
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 296
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 296
    Par défaut
    Plusieurs solutions :
    - spécialisation template : tu reconnais quand ton type stocké est un pointeur et applique les deletes en conséquence. Problème induit : si jamais tu peux ne pas être propriétaire du truc vers lequel tu pointes.
    boost propose divers helpers qui pourraient éventuellement te simplifier la vie. Les travaux d'Andrei Alexandrescu (Modern C++ Design chez Addisson-Wesley et quantité d'articles dans le C/C++ Users Journal) peuvent donner des idées quant à comment s'y prendre.

    - Ne jamais définir "CMyTpl<toto*>", mais "CMyTpl<boost::shared_ptr<toto> >". Cela règle le problème "induit" précédent. Solution adoptée par la STL. Enfin, pas vraiment adoptée vu que boost est arrivé après. Disons que c'est celle vers laquelle elle nous pousse. Ce qui me fait penser que tu as l'air de vouloir définir une collection. Tu as regardé ce qui existe déjà au moins ?

    PS: beurk les types racine de toute une hiérarchie.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : Etats-Unis

    Informations forums :
    Inscription : Juin 2002
    Messages : 256
    Par défaut
    Salut !

    MErci luc pour tes infos... mais pourrais tu expliquer plus en detailles la "spécialisation" puisque c'est exactement ce que je veux faire : reconnaitre si "typename T" est un pointeur ou autre.

    merci

  7. #7
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 296
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 296
    Par défaut
    Quelques petites remarques avant le code qui suit:
    * VC++ 6.5 m'a obligé à procéder à quelques petites feintes dans la mesure où il ne supporte pas la spécialisation partielle et d'autres trucs dans le genre => une classe template (type) à l'interieur de la spécialisation des holders.

    * J'ai utilisé boost pour reconnaitre si un type était un pointeur ou non et procéder à quelques conversions.

    * Le code qui suit n'est pas trop const-correct, une meilleure utilisation des outils de boost serait profitable.

    * J'ai volontairement enveloppé les pointeurs dans un std::auto_ptr<> histoire de ne pas avoir à me préoccuper d'écrire un destructeur qui appelra delete. L'emploi de boost::scope_ptr<> serait tout aussi intéressant et profitable. De fait, ces types n'étant pas prévus pour dupliquer le pointeur qu'ils référencent, j'ai interdit la recopie des holders et par extension de la classe template qui les utilise.
    Note en rapport : ces types d'enveloppeurs (wrappers) ne sont pas faits pour être employés dans des vecteurs qui savent se redimensionner.

    Autre note très importante : Si jamais tu comptes donner une sémantique de valeur à ta classe. Autrement dit, si tu comptes aussi pouvoir copier des éléments de ta classe. Alors une grosse réflexion est à prevoir sur le comment tu comptes réaliser cela. Voudras-tu:
    - partager le truc pointé entre toutes les instances de ta classe => remplace std::auto_ptr<> par boost::shared_ptr<> -- quelques part cette solution revient à utiliser la 2nde méthode que j'avais proposée dans mon post précédent, mais en automatique et plus compliqué.
    - copier le truc pointé, cela suppose que les éléments contenus soient copiables. De manière générale c'est faux si les trucs contenus n'ont pas une sémantique de valeur mais une sémantique de référence ; classique dès que les trucs pointés proviennent d'une hiérarchie de classes polymorphes
    - cloner le truc pointé, typiquement la chose à faire avec des objets qui ont une sémantique de référence.

    Ton problème : comment savoir automatiquement qu'elle est la bonne chose à appeler. La notion de police présentée dans Modern C++ Design serait une piste de recheche pour réaliser une telle chose. En toute honnêteté, je ne pense pas qu'il soit possible de faire un truc propre et beau qui soit facile à implémenter avec VC++.

    Et maintenant le code.
    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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    #include <iostream>
    #include <memory> // std::auto_ptr<>
    #include <boost/type_traits.hpp>
     
    // Le truc qui contient les éléments et ses deux spécialisations.
    template <bool is_pointer>
    struct holder_type {};
     
    template <>
    struct holder_type<false> {
        template <typename T>
        struct type {
            typedef T element_type;
            typedef T holded_type;
     
            type( element_type v ) : value_(v) {}
            element_type get() const { return value_; }
        private:
            holded_type value_;
        };
    };
     
    template <>
    struct holder_type<true> {
        template <typename T>
        struct type {
            typedef T element_type;
            typedef std::auto_ptr<typename boost::remove_pointer<T>::type> holded_type;
     
            type( element_type v ) : value_(v) {}
            element_type get() const { return value_.get(); }
        private:
            holded_type value_;
            type(type const &); // interdit à cause de std::auto_ptr<>
            type & operator=(type const &); // interdit à cause de std::auto_ptr<>
        };
    };
     
    // Le truc qui les contient
    template <typename T>
    class TrucTemplate 
    {
        typedef typename holder_type<boost::is_pointer<T>::value>::type<T> holder;
     
        holder holder_;
    public:
        TrucTemplate(const T & t) : holder_(t) {};
        T const value() const { return holder_.get();}
     
     
    };
     
    template <typename T>
    std::ostream & operator<<(std::ostream & os, const TrucTemplate<T> & tt)
    {
        return os << tt .value();
    }
     
    void test_TT() {
        std::cout << "\n----------------\n";
        TrucTemplate<int> tti ( 10 );
        std::cout << tti << std::endl;
        TrucTemplate<int *> ttpi ( new int(10) );
        std::cout << ttpi << std::endl;
    }
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  8. #8
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : Etats-Unis

    Informations forums :
    Inscription : Juin 2002
    Messages : 256
    Par défaut
    Merci !!!

  9. #9
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : Etats-Unis

    Informations forums :
    Inscription : Juin 2002
    Messages : 256
    Par défaut
    Rebonjours tout le monde !!

    J'ai trouvé une autre solution, basée sur celle de Luc. Je ne sais pas si elle est propre, mais elle marche, et ceux avec autant d'objets MyTpl que je veux (pourtant, je pensais que ca ne marcherait pas).

    Elle n'est pas trés "propre" mais a le mérite d'etre courte et claire :

    voici ce que j'ajoute dans le CTeur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    #define Is_Ptr ::boost::is_pointer<TYPE>::value;
    avec déclaré plus haut une variable membre de la classe MyTpl : bool Is_ptr;

    Et dans le CTeur de la structure :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
     #ifdef Is_Ptr true 
    		   delete m_Obj;
     #endif
    Miraculeusement, ca marche !

    merci encore de vos aides

  10. #10
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 296
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 296
    Par défaut
    énorme coup de bol si ça marche correctement.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  11. #11
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : Etats-Unis

    Informations forums :
    Inscription : Juin 2002
    Messages : 256
    Par défaut
    Et pourtant c'etait pas ma journée....

    J'avoue ne toujours pas comprendre pourquoi ca marche, mais le résultat est la.

    merci encore pour vos efforts

Discussions similaires

  1. shared_ptr, deleter et templates
    Par Freem dans le forum Langage
    Réponses: 4
    Dernier message: 05/09/2011, 12h23
  2. appliquer plusieurs templates
    Par Manu_Just dans le forum XSL/XSLT/XPATH
    Réponses: 7
    Dernier message: 04/04/2003, 16h26
  3. template match="node() mais pas text()"
    Par Manu_Just dans le forum XSL/XSLT/XPATH
    Réponses: 4
    Dernier message: 26/03/2003, 10h52
  4. [XSLT] template
    Par demo dans le forum XSL/XSLT/XPATH
    Réponses: 4
    Dernier message: 09/09/2002, 11h31

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