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

Langage C++ Discussion :

[Débutant]Foncteur et operator() template


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Sub
    Sub est déconnecté
    Membre averti
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mars 2003
    Messages : 20
    Par défaut [Débutant]Foncteur et operator() template
    Bonjour à tous.

    Je me suis récemment mis en tête de développer quelques petites classe pour faciliter le développement de mes programmes. Je suis développeur amateur(ainsi que débutant) et par conséquent c'est volontaire que je réinvente la roue.

    J'ai donc décidé de me faire une class New qui compterait le nombre de bytes alloué pour vérifier qu'il n'y a pas de fuite mémoire.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    class New
    {
        public :
            template<class T> T* operator() (void);
    };
    template<class T> T* New::operator() (void)
    {
        return new T;
    }
    Et je pensais pouvoir l'utiliser ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    int main(void)
    {
        int* n = New<int>();
     
        return EXIT_SUCCESS;
    }
    Et voilà donc les erreurs que j'obtiens :

    error: expected primary-expression before "int"
    error: expected `,' or `;' before "int"

    Ma question est donc simple : Quel chapitre sur les templates et les foncteurs ai-je loupé ?

  2. #2
    Inactif  
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    743
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 743
    Par défaut
    Tu appelles le constructeur, et pas l'operator() comme tu le voudrais.
    Il faut écrire à la place qqch du genre:
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    New<int> alloc;
    int* n = alloc();
    Ce que tu souhaites faire ressemble aux allocateurs de la STL... (enfin eux ne recomptent pas le nombre d'octets alloués, je vois pas comment faire d'ailleurs).
    Une fuite mémoire, c'est quand la mémoire n'est pas libérée, donc revérifier la taille de la mémoire allouée n'aide pas à contrôler les fuites. 'new' renvoit à la place une execption si y'a un problème (plus assez de mémoire)


    PS: et puis je m'aperçois que tu déclares mal ta classe New: tu devrais plutôt déclarer te classe template, et pas la fonction membre.
    (J'ai jamais essayé mais ça doit être coton d'utiliser un operator() avec des paramètres templates)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    template<class T> class New()
    {
      T *operator()() const {...}
    };

  3. #3
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    A ma connaissance il n'y a pas moyen de spécifier de paramètres template lorsque tu appelles un opérateur surchargé sous sa forme "courte" (tu pourrais par contre l'appeler ainsi j'imagine : New().operator()<int>()).

    Le mieux c'est encore d'oublier la surcharge d'opérateur et d'utiliser une fonction avec un joli nom explicite (Allocate() par exemple).

    Ou encore de surcharger les opérateurs new / delete directement.

  4. #4
    Sub
    Sub est déconnecté
    Membre averti
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mars 2003
    Messages : 20
    Par défaut
    Charlemagne >

    Eh bien en fait là j'ai juste mis la partie de la classe qui me pose problème, en réalité la fonction operator() est surchargée ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    template<class T> T* Truc::CNew::operator() (void)
    {
    	mNumberOfNew++;
    	mNumberOfBytesAllocated += sizeof(T);
    	return new T;
    }
    Et à côté j'ai une class Delete qui surcharge operator() ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    template<class T> void Truc::CDelete::operator() (T& objectToDelete)
    {
    	mNumberOfDelete++;
    	mNumberOfBytesDeallocated += sizeof(T*);
    	delete objectToDelete;
    }
    Et après par soustraction j'en déduis s'il y a eu autant de new que de delete et si le nombre de bytes alloué est le même que le nombre désaloué.

    Si c'est la classe que je déclare template, je serais obligé d'instancier un objet pour chaque type ce qui est tout sauf efficace de mon point de vue.

    Laurent Gomila >

    Après essai, New().operator()<int>() fonctionne effectivement mais du coup cela casse l'intérêt de ce que j'avais en tête, une fonction courte et pas trop moche. J'ai également pensé à la surcharge de new et delete mais je trouvais cela un peu trop "crade" sans vouloir te vexer (car j'ai lu ton excellent tutorial) et puis en plus j'ai pas encore le niveau pour m'aventurer dans ce genre de surcharge. Je vais donc me rabattre sur une fonction allocate d'une classe MemoryManager.

    Merci à vous deux.

  5. #5
    Membre émérite Avatar de mchk0123
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    816
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 816
    Par défaut
    Pendant que tu y est, tu peux faire hériter ta classe template MemoryManager d'une classe de base MemoryCounters (qui elle n'est pas template). Dans le but de stocker tes compteurs (qui sont je l'imagine communs à tous les types de variables allouées).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    class MemoryCounters {
      protected:
        int nb_bytes_allocateds;
        int nb_bytes_freeds;
    };
     
    template<typename T>
    class MemoryManager : public MemoryCounters {
       ...
       T* Allocate(...);
       ...
    };

  6. #6
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    Pendant que tu y est, tu peux faire hériter ta classe template MemoryManager d'une classe de base MemoryCounters (qui elle n'est pas template). Dans le but de stocker tes compteurs (qui sont je l'imagine communs à tous les types de variables allouées).
    Ce n'est pas le gestionnaire de mémoire qui est template, seulement ses fonctions new / delete

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    template<class T> void Mouuh::CDelete::operator() (T& objectToDelete)
    {
    	mNumberOfDelete++;
    	mNumberOfBytesDeallocated += sizeof(T*);
    	delete objectToDelete;
    }
    Ca n'a pas l'air correct. Pourquoi pas comme ça ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    template<class T> void Mouuh::CDelete::operator() (const T* objectToDelete)
    {
    	mNumberOfDelete++;
    	mNumberOfBytesDeallocated += sizeof(T);
    	delete objectToDelete;
    }
    A noter aussi qu'avec ce code tu vas te faire berner lorsque le polymorphisme entrera en jeu (tu vas allouer un Derivee* de X octets et le libérer sous forme de Base* qui ne fera que Y octets).

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [XSLT] Débutant erreur sur déclaration template
    Par nagdrir dans le forum XSL/XSLT/XPATH
    Réponses: 5
    Dernier message: 27/08/2007, 16h08
  2. Templates et Operator()
    Par Alp dans le forum C++
    Réponses: 7
    Dernier message: 14/01/2006, 13h41
  3. [Pb de débutant, et encore] surcharge operator =
    Par 10_GOTO_10 dans le forum C++Builder
    Réponses: 5
    Dernier message: 11/01/2006, 02h30
  4. Réponses: 4
    Dernier message: 08/11/2005, 15h10
  5. [Débutant] template <typename T> et main()
    Par reggae dans le forum Langage
    Réponses: 6
    Dernier message: 22/10/2005, 18h57

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