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 :

Réorganisation de code : fichier .cpp, .h et .inl.


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Invité
    Invité(e)
    Par défaut Réorganisation de code : fichier .cpp, .h et .inl.
    Salut,

    je voudrais réorganiser le code source de mon moteur car j'ai des fichiers.h avec des fonctions template et non template, bref, c'est un peu le bazard alors j'ai essyer de séparer ça dans 3 fichiers (le 1er ne contenant que les prototypes des fonctions template et non template, le second contenant la définition des fonctions template et le dernier contenant la définition des fonctions non templates, voici ce que ça donne :

    mon fichier .h :

    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
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
     
    #ifndef ODFAEG_ACTION_MAP_HPP
    #define ODFAEG_ACTION_MAP_HPP
    #include "action.h"
    /**
      *\namespace odfaeg
      * the namespace of the Opensource Development Framework Adapted for Every Games.
      */
    namespace odfaeg
    {
     
    /**
    * \file actionMap.h
    * \class ActionMap
    * \brief Store one action, a member function pointer and sf::Events.
    * \author Duroisin.L
    * \version 1.0
    * \date 1/02/2014
    * Store one or more triggered SFML Events and an ACTION.
    * Link the action to a pointer to a member function. (who's called when the action is triggered on an object)
    */
     
    class ODFAEG_CORE_API ActionMap
    {
    friend class Action;
    public :
        /** \fn ActionMap(Action action, FastDelegate<void> delegate)
        *  \brief Constructor :Construct an action map and link it to a member function, an action and an object
        of the class of the member function
        *  \param action : the action on which we want to bind the function.
        *  \param FastDelegate<void> the function to invoke throw the delegate when the action of the actionmap is triggered.
        */
        ActionMap (Action action, FastDelegate<void> delegate);
        /** \fn ActionMap(Action action, FastDelegate trigger, FastDelegate<void> command)
        *  \brief Constructor :Construct an action map and link it to a member function, an action and an object
        of the class of the member function
        *  \param action : the action on which we want to bind the function.
        *  \param FastDelegate<bool> : the function to invoke to test if the action is triggered.
        *  \param FastDelegate<void> the function to invoke throw the delegate when the action of the actionmap is triggered.
        */
        ActionMap (Action action, FastDelegate<bool> trigger, FastDelegate<void> command);
        /**\fn containsEvent (sf::Event &event)
        *  \brief check if the sf::Event is in the action map.
        *  \param the sf::Event to check in.
        *  \return true if the sf::Event is in the action map, false otherwise.
        */
        bool containsEvent (sf::Event &event);
        /** \fn bool isTriggered()
        *   \brief return true if the actionMap is triggered.
        *   \return true if the actionMap is triggered, false otherwise.
        */
        bool isTriggered();
        /** \fn bool containsBufferEvent(sf::Event& event)
        *   \brief check if the sf::Event is contained in the event buffer of an action
        *   \param the sf::Event to check with.
        */
        bool containsBufferEvent(sf::Event& event);
        /** \fn void clear ()
        *   \brief clear all the sf::events who are stored.
        */
        static void clear ();
        /** \fn void pushEvent (sf::Event& event)
        *   \brief store all the incoming sf::events which are triggered.
        *   \param the triggered sf::Event.
        */
        static void pushEvent (sf::Event& event);
        /** \fn void getEvents()
        *   \brief return all sfml events which are generated since the last event loop.
        *   \return the sfml event which are generated since the last loop.
        */
        static std::vector<sf::Event> getEvents();
        /** \fn void setParams(O* object, A... args)
        *   \brief change params of a command.
        *   \param O* object : the object of the actionmap's member function to call the function on.
        *   \param A... args : the arguments of the actionmap's member function to pass when the function is called.
        */
        template<typename O, typename ...A> void setParams(O* object, A... args);
        /** \fn void operator()()
        *   \brief call the member function linked to the action map and clear all the SFML events which are generated.
        */
        void operator()();
        /**\fn
        /* \brief remove an sf::Event from the stack.
        *  \param sf::Event event : the sfml event to remove from the stack.
        */
        static void removeEvent(sf::Event& event);
    private :
     
        /** \fn bool equalEvent (sf::Event event, sf::Event other)
        *   \brief test if two events are equal.
        *   \param sf::Event event : the event.
        *   \param sf::Event other : the otherevent.
        *   \return return true if the two events are equal.
        */
        static bool equalEvent (sf::Event& event, sf::Event& other);
        /** < the action mapped to the command.*/
        Action *action;
        /** < the function mapped to the command.*/
        FastDelegate<void> *delegate;
        /** < the trigger mapped to the command.*/
        FastDelegate<bool> *trigger;
        /** < the SFML events generated.*/
        static std::vector<sf::Event> events;
    };
    //#include "actionMap.inl"
    }
    #endif // ACTION_MAP
    mon fichier .inl

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    /** \fn void setParams(O* object, A... args)
    *   \brief change params of a command.
    *   \param O* object : the object of the actionmap's member function to call the function on.
    *   \param A... args : the arguments of the actionmap's member function to pass when the function is called.
    */
    template<typename O, typename ...A> void ActionMap::setParams(O* object, A... args) {
        delegate->setParams(object, args...);
    }
    Et mon fichier .cpp

    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
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
     
    #include "../../../include/odfaeg/Core/actionMap.h"
    namespace odfaeg {
    std::vector<sf::Event> ActionMap::events = std::vector<sf::Event> ();
    /** \fn ActionMap(Action action, FastDelegate<void> delegate)
    *  \brief Constructor :Construct an action map and link it to a member function, an action and an object
    of the class of the member function
    *  \param action : the action on which we want to bind the function.
    *  \param FastDelegate<void> the function to invoke throw the delegate when the action of the actionmap is triggered.
    */
    ActionMap::ActionMap (Action action, FastDelegate<void> delegate)
    {
        this->action = new Action(action);
        this->delegate = new FastDelegate<void>(delegate);
        trigger = nullptr;
     
    }
    /** \fn ActionMap(Action action, FastDelegate trigger, FastDelegate<void> command)
    *  \brief Constructor :Construct an action map and link it to a member function, an action and an object
    of the class of the member function
    *  \param action : the action on which we want to bind the function.
    *  \param FastDelegate<bool> : the function to invoke to test if the action is triggered.
    *  \param FastDelegate<void> the function to invoke throw the delegate when the action of the actionmap is triggered.
    */
    ActionMap::ActionMap (Action action, FastDelegate<bool> trigger, FastDelegate<void> command) {
        this->action = new Action(action);
        this->delegate = new FastDelegate<void>(command);
        this->trigger = new FastDelegate<bool>(trigger);
    }
    /**\fn containsEvent (sf::Event &event)
    *  \brief check if the sf::Event is in the action map.
    *  \param the sf::Event to check in.
    *  \return true if the sf::Event is in the action map, false otherwise.
    */
    bool ActionMap::containsEvent (sf::Event &event)
    {
        std::vector<sf::Event>::iterator it;
        for (it = events.begin(); it != events.end(); it++)
        {
            if (equalEvent(event, *it))
                return true;
        }
        return false;
    }
    /** \fn bool isTriggered()
    *   \brief return true if the actionMap is triggered.
    *   \return true if the actionMap is triggered, false otherwise.
    */
    bool ActionMap::isTriggered()
    {
        if (trigger == nullptr && action->isTriggered())
        {
            action->clearEventsBuffers();
            return true;
        } else if ((*trigger)() && action->isTriggered()) {
            action->clearEventsBuffers();
            return true;
        }
        return false;
    }
    /** \fn bool containsBufferEvent(sf::Event& event)
    *   \brief check if the sf::Event is contained in the event buffer of an action
    *   \param the sf::Event to check with.
    */
    bool ActionMap::containsBufferEvent(sf::Event& event) {
        return action->containsEvent(event);
    }
    /** \fn void clear ()
    *   \brief clear all the sf::events who are stored.
    */
    void ActionMap::clear ()
    {
        events.clear();
    }
    /** \fn void pushEvent (sf::Event& event)
    *   \brief store all the incoming sf::events which are triggered.
    *   \param the triggered sf::Event.
    */
    void ActionMap::pushEvent (sf::Event& event)
    {
        std::vector<sf::Event>::iterator it;
        bool containsEvent = false;
        for (it = events.begin(); it != events.end(); it++)
        {
            if (equalEvent(event, *it))
                containsEvent = true;
        }
        if (!containsEvent)
            events.push_back(event);
    }
    /** \fn void getEvents()
    *   \brief return all sfml events which are generated since the last event loop.
    *   \return the sfml event which are generated since the last loop.
    */
    std::vector<sf::Event> ActionMap::getEvents()
    {
        return events;
    }
     
    /** \fn void operator()()
    *   \brief call the member function linked to the action map and clear all the SFML events which are generated.
    */
    void ActionMap::operator()()
    {
        (*delegate)();
        action->clearEventsBuffers();
    }
    /**\fn
    /* \brief remove an sf::Event from the stack.
    *  \param sf::Event event : the sfml event to remove from the stack.
    */
    void ActionMap::removeEvent(sf::Event& event) {
        std::vector<sf::Event>::iterator it;
        for (it = events.begin(); it != events.end();) {
            if (equalEvent(*it, event))
                it = events.erase(it);
            else
                it++;
        }
    }
    bool ActionMap::equalEvent (sf::Event& event, sf::Event& other) {
        if (event.type != other.type)
            return false;
        if (event.type == sf::Event::Resized)
        {
            return event.size.width == other.size.width && event.size.height == other.size.height;
        }
        if (event.type == sf::Event::TextEntered)
        {
            return event.text.unicode == other.text.unicode;
        }
        if (event.type == sf::Event::KeyPressed || event.type == sf::Event::KeyReleased)
        {
            return event.key.code == other.key.code;
        }
        if (event.type == sf::Event::MouseWheelMoved)
        {
            return event.mouseWheel.delta == other.mouseWheel.delta;
        }
        if (event.type == sf::Event::MouseButtonPressed || event.type == sf::Event::MouseButtonReleased)
        {
            return event.mouseButton.button == other.mouseButton.button;
        }
        if (event.type == sf::Event::MouseMoved)
        {
            return event.mouseMove.x == other.mouseMove.x && event.mouseMove.y == other.mouseMove.y;
        }
        if (event.type == sf::Event::JoystickButtonPressed || event.type == sf::Event::JoystickButtonReleased)
        {
            return event.joystickButton.joystickId == other.joystickButton.joystickId
                   && event.joystickButton.button == other.joystickButton.button;
        }
        if (event.type == sf::Event::JoystickMoved)
        {
            return event.joystickMove.joystickId == other.joystickMove.joystickId
                   && event.joystickMove.position == other.joystickMove.position;
        }
        return false;
    }
    }
    Seulement ça ne marche pas lorsque j'appelle la fonction setParams, j'ai une erreur de référence indéfinie.

    Comment faire ça correctement ?

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    Ta fonction template n'est pas inline. Il est donc étrange de la mettre dans un fichier .inl.

    Pourquoi, dans ton .h, as-tu commenté l'inclusion de ton .inl ?

  3. #3
    Invité
    Invité(e)
    Par défaut
    Ha oui juste je dois la mettre inline, je vais devoir faire ça pour toutes les fonctions courte que j'utilise souvent d'ailleurs. (Et pas que les fonction template)

    Bref apparemment on peut pas séparer les fonctions templates on est obligé des les définir dans le .h, je l'ai donc inclus ici :

    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
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
     
    #ifndef ODFAEG_ACTION_MAP_HPP
    #define ODFAEG_ACTION_MAP_HPP
    #include "action.h"
    /**
      *\namespace odfaeg
      * the namespace of the Opensource Development Framework Adapted for Every Games.
      */
    namespace odfaeg
    {
     
    /**
    * \file actionMap.h
    * \class ActionMap
    * \brief Store one action, a member function pointer and sf::Events.
    * \author Duroisin.L
    * \version 1.0
    * \date 1/02/2014
    * Store one or more triggered SFML Events and an ACTION.
    * Link the action to a pointer to a member function. (who's called when the action is triggered on an object)
    */
     
    class ODFAEG_CORE_API ActionMap
    {
    friend class Action;
    public :
        /** \fn ActionMap(Action action, FastDelegate<void> delegate)
        *  \brief Constructor :Construct an action map and link it to a member function, an action and an object
        of the class of the member function
        *  \param action : the action on which we want to bind the function.
        *  \param FastDelegate<void> the function to invoke throw the delegate when the action of the actionmap is triggered.
        */
        ActionMap (Action action, FastDelegate<void> delegate);
        /** \fn ActionMap(Action action, FastDelegate trigger, FastDelegate<void> command)
        *  \brief Constructor :Construct an action map and link it to a member function, an action and an object
        of the class of the member function
        *  \param action : the action on which we want to bind the function.
        *  \param FastDelegate<bool> : the function to invoke to test if the action is triggered.
        *  \param FastDelegate<void> the function to invoke throw the delegate when the action of the actionmap is triggered.
        */
        ActionMap (Action action, FastDelegate<bool> trigger, FastDelegate<void> command);
        /**\fn containsEvent (sf::Event &event)
        *  \brief check if the sf::Event is in the action map.
        *  \param the sf::Event to check in.
        *  \return true if the sf::Event is in the action map, false otherwise.
        */
        bool containsEvent (sf::Event &event);
        /** \fn bool isTriggered()
        *   \brief return true if the actionMap is triggered.
        *   \return true if the actionMap is triggered, false otherwise.
        */
        bool isTriggered();
        /** \fn bool containsBufferEvent(sf::Event& event)
        *   \brief check if the sf::Event is contained in the event buffer of an action
        *   \param the sf::Event to check with.
        */
        bool containsBufferEvent(sf::Event& event);
        /** \fn void clear ()
        *   \brief clear all the sf::events who are stored.
        */
        static void clear ();
        /** \fn void pushEvent (sf::Event& event)
        *   \brief store all the incoming sf::events which are triggered.
        *   \param the triggered sf::Event.
        */
        static void pushEvent (sf::Event& event);
        /** \fn void getEvents()
        *   \brief return all sfml events which are generated since the last event loop.
        *   \return the sfml event which are generated since the last loop.
        */
        static std::vector<sf::Event> getEvents();
     
        /** \fn void operator()()
        *   \brief call the member function linked to the action map and clear all the SFML events which are generated.
        */
        void operator()();
        /**\fn
        /* \brief remove an sf::Event from the stack.
        *  \param sf::Event event : the sfml event to remove from the stack.
        */
        static void removeEvent(sf::Event& event);
        #include "actionMap.inl"
    private :
     
        /** \fn bool equalEvent (sf::Event event, sf::Event other)
        *   \brief test if two events are equal.
        *   \param sf::Event event : the event.
        *   \param sf::Event other : the otherevent.
        *   \return return true if the two events are equal.
        */
        static bool equalEvent (sf::Event& event, sf::Event& other);
        /** < the action mapped to the command.*/
        Action *action;
        /** < the function mapped to the command.*/
        FastDelegate<void> *delegate;
        /** < the trigger mapped to the command.*/
        FastDelegate<bool> *trigger;
        /** < the SFML events generated.*/
        static std::vector<sf::Event> events;
    };
     
    }
    #endif // ACTION_MAP
    Et là ça marche mais je sais pas si c'est la meilleur manière de faire. :X

    PS : sinon les fichier .inl sont les seuls qui sont coloré dans code::blocks...., j'ai essayer de mettre .tpp mais ça ne colore pas.

  4. #4
    Membre Expert
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Par défaut
    Citation Envoyé par Lolilolight Voir le message
    Et là ça marche mais je sais pas si c'est la meilleur manière de faire. :X

    PS : sinon les fichier .inl sont les seuls qui sont coloré dans code::blocks...., j'ai essayer de mettre .tpp mais ça ne colore pas.
    Le code de ton premier post était la bonne façon de faire. Pour Code::Blocks, probablement une simple option de configuration.

    Niveau code, ça donne ça
    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
    //foo.h
    #pragma once
    struct Foo {
    	template <class T>
    	T bar() const;
     
    	int baz() const;
    };
    #include "foo.tpp"
     
    // foo.tpp
    template <class T>
    T Foo::bar() const {
    	return T();
    }
     
    // foo.cpp
    #include "foo.h"
     
    int Foo::baz() const {
    	return 42;
    }
    Citation Envoyé par oodini Voir le message
    Pourquoi, dans ton .h, as-tu commenté l'inclusion de ton .inl ?
    Je pense aussi que l'erreur vient de là.

  5. #5
    Invité
    Invité(e)
    Par défaut
    Oui ma première méthode était la bonne j'avais juste oublié le ActionMap:: devant le nom de la fonction dans le fichier .tpp et, de décommenter cette ligne de code.

  6. #6
    Membre éclairé
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Août 2012
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Architecte de système d'information
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2012
    Messages : 44
    Par défaut
    Je déteste les fichiers tpl, ou inl. A quoi bon creer ces fichiers alors que tu as besoins de les inclure de toute facon, soit quelque part discretement dans ton .h, soit explicitement dans tes cpp.

    Le corps des templates doit etre visible par tout ou ils sont utilises, mettons les a la fin des headers, tout le monde sera content.

    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
    // Fichier Foo.h
    #ifndef __FOO__H
    #define __FOO__H
     
    template <class T>
    class Foo {
        void faireCi();
     
        template <class U>
        void faireCa();
    }; // mon interface fini ici
     
    // la partie implementation, a ignorer pour les developpeurs qui utilisent la classe Foo
    template <class T>
    void Foo::faireCi() {
    // blah blah
    }
     
    template <class T, class U>
    void Foo::faireCa() {
    // blah blah
    }
    #endif // __FOO__H
    //Fin de fichier Foo.h

  7. #7
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    Citation Envoyé par forrestdg Voir le message
    Je déteste les fichiers tpl, ou inl. A quoi bon créer ces fichiers alors que tu as besoins de les inclure de toute façon, soit quelque part discrètement dans ton .h, soit explicitement dans tes cpp.
    Cela sert à séparer la déclaration de l'implémentation.

    Citation Envoyé par forrestdg Voir le message
    Le corps des templates doit être visible par tout ou ils sont utilises, mettons les a la fin des headers, tout le monde sera content.
    Tout le monde sera également content si un include est mis à la fin des headers. Sauf les râleurs.

Discussions similaires

  1. definition de code au fichier.cpp
    Par info_ dans le forum C++
    Réponses: 9
    Dernier message: 05/04/2010, 12h51
  2. Fichier cpp et ActiveX
    Par 1300371 dans le forum Visual C++
    Réponses: 12
    Dernier message: 11/07/2006, 11h24
  3. plusieurs fichiers cpp
    Par elekis dans le forum C++
    Réponses: 2
    Dernier message: 11/05/2006, 06h36
  4. Fichier .cpp
    Par sourivore dans le forum Windows
    Réponses: 5
    Dernier message: 03/05/2006, 15h04
  5. Réponses: 7
    Dernier message: 22/11/2005, 14h05

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