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 :

Cas de const-science


Sujet :

Langage C++

  1. #1
    Membre Expert

    Avatar de germinolegrand
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Octobre 2010
    Messages
    738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Octobre 2010
    Messages : 738
    Par défaut Cas de const-science
    Bonjour,

    si un attribut doit être constant, mais qu'il doit être initialisé dans le corps du constructeur, comment fait-on ? const_cast ?

    Qu'est-ce qui est recommandé ? J'avoue avoir du mal à placer un const_cast vu la réputation qu'il a .

  2. #2
    screetch
    Invité(e)
    Par défaut
    pourquoi doit-il etre initialise dans le corps du constructeur?

    dans tous les cas ou ca semblait impossile, j'ai reussi a l'initialiser quand meme en faisant une fonction libre. Peux tu montrer ton exemple?

  3. #3
    Membre Expert

    Avatar de germinolegrand
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Octobre 2010
    Messages
    738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Octobre 2010
    Messages : 738
    Par défaut
    il doit être déterminé dans le constructeur parce sa valeur est déterminée par un algorithme (avec une connexion réseau) qui manipule l'objet lui-même. Une fonction libre ne fonctionnerait je pense pas puisque déterminer cette valeur nécessite d'utiliser l'objet lui-même... or pour pouvoir l'utiliser il faut qu'il soit initialisé... non ?

    As-t-on le droit de modifier un objet en cours d'initialisation (entendez par là que la liste d'initialisation n'est qu'à moitié exécutée) ?

    L'exemple épuré :
    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
     
    class Network
    {
    public:
        Network(sf::IpAddress join);
        Network(const Network&) = delete;
     
        virtual ~Network();
     
    private:
     
        const ServerId m_id = 1;
        std::map<ServerId, std::unique_ptr<sf::TcpSocket>> m_otherServers;
    };
     
    Network::Network(sf::IpAddress join)
    {
        //l'algorithme doit se connecter et donc modifier m_otherServers
        //afin de récupérer la valeur attribuée par le serveur distant à m_id
    }

  4. #4
    screetch
    Invité(e)
    Par défaut
    dans ce cas, je creerais un objet intermediaire que je copierais dans un champ const


    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
    class IntermediateNetwork
    {
        friend class Network;
    public:
        IntermediateNetwork(sf::IpAddress join);
        IntermediateNetwork(const Network&) = delete;
     
        virtual ~IntermediateNetwork();
     
    private:
     
        ServerId m_id = 1;
        std::map<ServerId, std::unique_ptr<sf::TcpSocket>> m_otherServers;
    };
     
    IntermediateNetwork::IntermediateNetwork(sf::IpAddress join)
    {
      // ton code
    }
     
    class Network
    {
    public:
        Network(sf::IpAddress join);
        Network(const Network&) = delete;
     
        virtual ~Network();
     
    private:
         const IntermediateNetwork m_implementation;
    };
     
    Network(sf::IpAddress join)
      : m_implementation(join)
    {
      // maintenant le IntermediateNetwork est const
      // donc le m_serverId aussi
    }
    //edit
    on peut modifier un objet en coursde construction a condition qu'il ait deja ete construit, l'exemple marcherait comme ca:




    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
    class Network
    {
    public:
        Network(sf::IpAddress join);
        Network(const Network&) = delete;
     
        virtual ~Network();
     
    private:
         // ATTENTION, les initialisations sont faites dans l'ordre
         // de leurs declarations dans la classe, donc mettre le
         // champ modifiable en premier
         std::map<ServerId, std::unique_ptr<sf::TcpSocket>> m_otherServers;
         const ServerId m_id = 1;
     
         static ServerId doConnectToIP(std::map& serverList, sf::IpAddress join);
    };
     
    Network::Network(sf::IpAddress join)
     : m_otherServers()
     , m_id(doConnectToIP(m_otherServers, join)
    {
    }
    je ne suis pas sur d'avoir compris exactement quel champ est const et doit etre modifie mais j'espere que ce que j'ai dit ci dessus est assez clair.
    Dernière modification par screetch ; 21/10/2012 à 23h26.

  5. #5
    Membre Expert

    Avatar de germinolegrand
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Octobre 2010
    Messages
    738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Octobre 2010
    Messages : 738
    Par défaut
    Euh... le premier exemple ne résout pas le problème puisque tu essaies toujours de modifier un const dans le constructeur de Intermediate
    Par contre ton 2e exemple me semble plus pertinent...

  6. #6
    screetch
    Invité(e)
    Par défaut
    ah pardon, je voulais retirer le const de IntermediateNetwork.
    Ensuite tu constifies IntermediateNetwork ce qui rend par ricochet tous les champs constants.
    Edit numero 2

  7. #7
    Membre Expert

    Avatar de germinolegrand
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Octobre 2010
    Messages
    738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Octobre 2010
    Messages : 738
    Par défaut
    le problème étant que j'ai besoin de m_otherServers en non-const par la suite...

    edit: tout ça pour un misérable const int peut-être que la meilleure solution serait de virer le const tout simplement ?
    (ça résout ce problème particulier mais pas le cas général)

    edit2: j'aime bien le verbe constifier, ça fait un peu pétrifier ou constiper...

  8. #8
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    Pourquoi ne pas pousser plus loin la proposition de screetch ?

    Tu crées une première classe qui s'initialise, qui serait identique à ce que tu as aujourd'hui mais avec aucun attributs const.
    Et ta vraie class comme tu le souhaites avec les constances de ton choix pour chaque attribut. Leur initialisation se faisant par la liste d'initialisation, donc plus de problème
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  9. #9
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 636
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 636
    Par défaut
    Salut,

    A vrai dire, je me demande pourquoi tu voudrais rendre m_Id "uniquement" constant...


    Ce faisant, c'est comme si tu disait:
    Je vais avoir une foule d'instances de Network et toutes ces instances vont avoir la même id
    Mais...

    Soit c'est vrai, et dans ce cas, ton id a de grandes chances de pouvoir être static, constant et, pourquoi pas, publique (dés le moment où il est ... constant et statique ), car m_id est simplement un invariant dont tu peux souhaiter disposer à "n'importe quel moment" depuis "n'importe où", indépendant de toute instance de ta classe.

    Soit, tu peux, effectivement, avoir plusieurs réseaux ayant chacun un id différente, et, dans ce cas, l'id du réseau sera déterminée "par ailleurs"...

    Dans ce cas, ton id n'a absolument pas à être constante, il faut juste veiller à ce que les fonctions qui utiliseront id soient constantes.

    De toutes façons, une fois que m_otherServers aura été remplie, tu ne devras plus modifier ton instance de Network, sauf cas exceptionnel où tu voudrais ajouter / supprimer un autre serveur, voir mettre la liste des serveurs à jour !

    En déclarant toutes les fonctions qui n'ont rien à voir avec la mise à jour de la liste de serveurs constantes, tu auras la certitude qu'elles ne pourront modifier ni m_id ni m_otherServers.

    Au final, au pire, tu auras quelque chose comme
    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
    class Network
    {
        public:
            Network(sf::IpAddress join);
            /* les seules fonctions non constantes à avoir */
            void addServerToList(serverId );
            void removeServerFromList(serverId);
            void updateServerList();
            /* et toutes les fonctions qui n'ont rien à voir avec la mise à
             * jour qui sont constantes
             */
            void foo1() const;
            void foo2(/* ... */ ) const;
            /* ... */
            void barN() const;
           /* mais SURTOUT PAS LA FONCTION
            void setId(ServerId newid)
            {
                 m_id =newid;
            }
            */
        private:
     
            ServerId m_id = 1;
            std::map<ServerId, std::unique_ptr<sf::TcpSocket>> m_otherServers;
    };
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  10. #10
    Membre Expert

    Avatar de germinolegrand
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Octobre 2010
    Messages
    738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Octobre 2010
    Messages : 738
    Par défaut
    l'utilisation de m_id est tout à fait localisée à cette classe.
    L'idée c'est de rejoindre un réseau, celui-ci nous attribue un ID qui sera fixe jusqu'à la fin du programme/crash du serveur. Network est la classe qui gère les échanges réseau, elle-seule a besoin de cet ID pour le fixer en en-tête de tous les messages et le comparer avec les entêtes des messages reçus afin de ne pas faire transiter des messages déjà traités. De plus l'ajout/suppression d'un autre serveur peut surgir n'importe quand. La suppression particulièrement parce que toute fonction rencontrant une erreur sur une communication détruira la connexion avec le serveur correspondant, le considérant comme mort.

    P.S: ton code contient toujours un const sur le m_id

  11. #11
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 636
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 636
    Par défaut
    Citation Envoyé par germinolegrand Voir le message
    l'utilisation de m_id est tout à fait localisée à cette classe.

    L'idée c'est de rejoindre un réseau, celui-ci nous attribue un ID qui sera fixe jusqu'à la fin du programme/crash du serveur. Network est la classe qui gère les échanges réseau, elle-seule a besoin de cet ID pour le fixer en en-tête de tous les messages et le comparer avec les entêtes des messages reçus afin de ne pas faire transiter des messages déjà traités. De plus l'ajout/suppression d'un autre serveur peut surgir n'importe quand. La suppression particulièrement parce que toute fonction rencontrant une erreur sur une communication détruira la connexion avec le serveur correspondant, le considérant comme mort.
    Je dirais que c'est une raison de plus !

    Tu crées une fonction "connectNetwork" (par exemple), non constante et privée, qui se chargera de se connecter, d'obtenir l'id de ton instance, et de remplir ta liste de serveurs, qui n'est appelée, dans un premier temps que dans les consructeurs, puis tu n'y touche plus!

    Note que, à bien y réfléchir...

    On peut se poser la question de savoir "que va-t-il se passer si le serveur crashe" au niveau de ton application.

    Si tu dois faire le tour de tous les pc sur lesquels ton application tourne pour la relancer suite à un crash serveur, ca va pas forcément être folichon

    On pourrait donc parfaitement envisager d'apporter une certaine "tolérance" face au crash serveur en faisant en sorte que, si l'application se rend compte que le serveur ne répond plus (quelle qu'en soit la raison ), elle tente de se reconnecter à intervalle régulier.

    Mais, si c'est le cas, aussi bien l'id que la liste des autres serveurs risquent d'être différents après la reconnection, et il faudra donc mettre tout cela à jour.

    Il serait peut etre donc aussi intéressant de prévoir une fonction publique, non constante, "reconnect" qui vide la liste des serveurs et qui invoque par la suite la fonction connectToServeur

    Je réfléchis peut etre trop loin, mais c'est sans doute une réflexion que tu finiras sans doute par avoir tot ou tard
    P.S: ton code contient toujours un const sur le m_id
    Juste une erreur de copier / coller ... Elle est corrigée (et le code a d'ailleurs été un peu modifié )
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  12. #12
    Membre Expert

    Avatar de germinolegrand
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Octobre 2010
    Messages
    738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Octobre 2010
    Messages : 738
    Par défaut
    La tentative de reconnexion régulière serait une grosse faille de sécurité. Ça serait la même chose que de laisser un listener ouvert en permanence pour accéder au réseau.
    On ne fait une connexion que sur ordre express de quelqu'un d'humain, ou d'un script externe ayant accès à l'entrée standard du programme.

    De plus à la connexion il n'y a pas qu'une simple connexion, il y a (en gros) : connexion à un serveur qui va rediriger cette connexion après vérification des mots de passe etc. vers plusieurs serveurs auquel le nouveau serveur devra se connecter, puis équilibrage de la charge de travail entre les différents services.

    Si un serveur est déconnecté d'un serveur mais pas d'un autre, alors il demande simplement un rééquilibrage des connexions (pas nécessairement avec le serveur précédent).

  13. #13
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 636
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 636
    Par défaut
    Je me suis peut etre mal exprimé, mais l'idée est de savoir ce qui se passe si le serveur crashe...

    Tu seras sans doute d'accord avec moi que faire planter purement et simplement l'application n'est sans doute pas une solution acceptable !

    Tout comme tu seras sans doute d'accord avec moi pour dire que, même si tu tentes de te connecter sur un autre serveur, la logique apportée par la fonction reconnect est, hormis le choix du serveur, sensiblement identique à ce que j'ai décrit

    Tu as raison de pinailler sur la sécurité, mais, même si c'est sur une intervention de l'utilisateur que la reconnexion s'effectue, il est sans doute bon de prévoir le moyen de la provoquer (ou de provoquer le rééquilibrage des connexions)
    [EDIT] et que cette reconnexion / ce rééquilibrage peut parfaitement provoquer un changement de réseau et donc d'id
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  14. #14
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 636
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 636
    Par défaut
    Ce qu'il faut, surtout, comprendre, c'est que, dans l'absolut, ce n'est pas le membre m_id qui doit être constant, mais l'utilisation globale (hors cas particuliers) de ton instance qui doit travailler "comme si l'instance était constante" et que la grosse majorité des fonctions peut donc être déclarée comme constante, car s'engageant à ne pas modifier l'état de l'instance au départ de laquelle elles (les fonctions membres) sont appelées.

    A coté de cette majorités de fonction déclarées constantes, on peut entrevoir "quelques" fonctions qui justifient de modifier l'état de l'instance de Network au départ de laquelle elles sont appelées.

    ces quelques fonctions seront celles de (re) connexion et de mise à jour de la liste des serveurs.

    L'avantage de déclarer les fonctions "qui n'ont aucune raison de modifier l'état de l'instance au départ de laquelle elle sont appelées" comme étant constante, c'est que si tu viens, dans l'une de ces fonctions, à invoquer (par mégarde, sans doute) une fonction non constante (et qui risque donc de modifier l'état de l'objet courent), le compilateur t'insultera haut et fort
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  15. #15
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 292
    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 292
    Par défaut
    Petite parenthèse sur un aspect important que je n'ai pas vu abordé -- j'ai lu en diagonale.
    -> Les tests.

    Si tu veux pouvoir tester facilement ta classe, fait de l'id un truc donné à la construction et non un truc calculé à la construction en allant taper dans une ressource globale et quasi-externe.
    Ainsi tu pourras mettre tous les const que tu veux -- à bon ou mauvais escient --, mais surtout tu seras en mesaure d'écrire des test-unitaires et autres tests fonctionnels/d'intégration de plus haut niveau.
    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...

  16. #16
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 636
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 636
    Par défaut
    Citation Envoyé par Luc Hermitte Voir le message
    Petite parenthèse sur un aspect important que je n'ai pas vu abordé -- j'ai lu en diagonale.
    -> Les tests.

    Si tu veux pouvoir tester facilement ta classe, fait de l'id un truc donné à la construction et non un truc calculé à la construction en allant taper dans une ressource globale et quasi-externe.
    Ainsi tu pourras mettre tous les const que tu veux -- à bon ou mauvais escient --, mais surtout tu seras en mesaure d'écrire des test-unitaires et autres tests fonctionnels/d'intégration de plus haut niveau.
    +1...

    En fait, je venais de penser à une question qui n'a pas encore été abordée... : Quelle est la responsabilité réelle de ta classe Network

    J'aurais tendance, à voir ses membres privés, à dire que sa responsabilité est de maintenir une sorte de "mapping" du réseau.

    Si je ne me trompe pas, alors, la responsabilité de la gestion de la connexion n'échoit, en vertu du principe de la responsabilité unique, pas à ta classe Network, mais bien à "quelque chose d'externe", à savoir sans doute une classe "Connexion" (ou similaire).

    Et la responsabilité de cette classe n'est d'ailleurs que de "maintenir la connexion active" (ou de la réactiver en cas de besoin, selon le genre de projet auquel tu as affaire).

    Dans ce cas, c'est, toujours en vertu du principe de la responsabilité unique, sans doute une troisième classe ( "RequestSender" ou un de ses dérivé si c'est une classe abstraite ) qui utilisera la connexion pour envoyer la requete permettant d'obtenir l'id du réseau / la liste des serveurs opérationnels.

    Et c'est cette classe là (ou les classes qui en dérivent) qui devrait être utilisée par ta classe Network aussi bien pour déterminer la valeur de m_id que le contenu de m_otherServers.

    A ce moment là, rien ne t'empêcherait, a priori, de déclarer m_id comme étant constant, car tu peux utiliser son (pseudo) constructeur en appelant la classe (dérivée de) RequestSender pour obtenir l'id du réseau.

    Ton constructeur pourrait donc ressembler à quelque chose comme

    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
    class Network
    {
        public:
            /* on considère que IdRequestSender dérive de RequestSender
             * et que ces classes sont en mesure d'obtenir ou de de mettre une 
             * connexion en place en n'ayant que l'ip à contacter, mais ca, c'est
             * un autre problème ;)
             */
            Network(sf::IpAddress join): m_id(IdRequestSender(join).send().toint())
            {
            }
     
        private:
     
            const ServerId m_id = 1;
            std::map<ServerId, std::unique_ptr<sf::TcpSocket>> m_otherServers;
    };
    Après, il reste le problème de "quoi faire en cas de déconnexion"...

    J'ai plaidé pour le fait qu'il était sans doute préférable de tenter une reconnexion, quitte à ce que ce ne soit que sur intervention de l'utilisateur ou à ce que ce ne soit en fait qu'un "rééquilibrage" de la connexion.

    Mais le problème est de savoir si l'on va réellement garder la même valeur pour m_id ou s'il est acceptable de détruire purement et simplement l'instance de Network pour en recréer une avec une nouvelle valeur de m_id si celle-ci vient à changer.

    Je ne connais simplement pas la réponse à cette question car je n'ai pas une connaissance suffisante de ton projet pour y répondre, mais je te conseille vraiment de réfléchir à ce qu'il est acceptable de faire si la valeur de m_id vient à changer

    S'il est acceptable de détruire ton instance de Network et d'en recréer une, pas de problème, laisses donc m_id constant, mais, si tu viens à estimer que c'est inacceptable, tu n'auras pas le choix: il faudra forcément le rendre non constant et te reposer sur la constance des fonctions membres de ta classe Network pour s'assurer qu'il ne sera pas modifié inopinément
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  17. #17
    Membre Expert

    Avatar de germinolegrand
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Octobre 2010
    Messages
    738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Octobre 2010
    Messages : 738
    Par défaut
    Merci pour vos reponses et désole de l'absence des miennes car je suis privé de connexion internet pour une raison indéterminée. (suis sur mon mobile)

    Tout d'abord il ne doit y avoir qu'un seul réseau. Un serveur est soit sur le reseau, soit éteint.

    Il s'agit d'un réseau mesh dont tous les serveurs disposent du même code source.

    Pour ce qui est de la connexion perdue, elle le reste. Si un serveur vient à se trouver en dessous du seuil minimum de connexion, il demandera un rééquilibrage des connexions.

    Mais en aucun cas un serveur ne peut changer d'id (c'est comme votre n¤ de sécu).
    De plus un serveur ne se connecte qu'une seule fois.

    Mais en effet c'est peut-être à la classe ConnectionService (elle existe) de s'en occuper... Le problème c'est que cette classe est un Service, qui a donc besoin d'une reference sur Network pour s'initialiser... Bref on tourne en rond

    Il est à noter que je n'ai présenté plus haut qu'une (petite) partie de la classe Network qui a en charge de recevoir les messages et de les envoyer au service concerné ainsi que de faire circuler les messages entre les serveurs, le tout en multithreadé.

  18. #18
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 636
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 636
    Par défaut
    Citation Envoyé par germinolegrand Voir le message
    Merci pour vos reponses et désole de l'absence des miennes car je suis privé de connexion internet pour une raison indéterminée. (suis sur mon mobile)

    Tout d'abord il ne doit y avoir qu'un seul réseau. Un serveur est soit sur le reseau, soit éteint.

    Il s'agit d'un réseau mesh dont tous les serveurs disposent du même code source.

    Pour ce qui est de la connexion perdue, elle le reste. Si un serveur vient à se trouver en dessous du seuil minimum de connexion, il demandera un rééquilibrage des connexions.

    Mais en aucun cas un serveur ne peut changer d'id (c'est comme votre n¤ de sécu).
    De plus un serveur ne se connecte qu'une seule fois.

    Mais en effet c'est peut-être à la classe ConnectionService (elle existe) de s'en occuper... Le problème c'est que cette classe est un Service, qui a donc besoin d'une reference sur Network pour s'initialiser... Bref on tourne en rond

    Il est à noter que je n'ai présenté plus haut qu'une (petite) partie de la classe Network qui a en charge de recevoir les messages et de les envoyer au service concerné ainsi que de faire circuler les messages entre les serveurs, le tout en multithreadé.
    Hé bien, peut etre que le problème vient justement de ta classe ConnectionService...

    Poses-toi, peut être, la question de ce qui est absolument nécessaire pour le maintient de la connexion!

    A priori, je dirais qu'il lui faut:
    • une ip à contacter
    • un login
    • un mot de passe
    • ET C'EST TOUT
    Si ta classe ConnectionService a besoin que ta classe Network soit initialisée pour travailler, mais que ta classe Network a besoin d'une instance fonctionnelle de ConnectionService pour pouvoir être correctement initialisée, c'est qu'il y a, visiblement, un problème quelque part.

    Peut etre n'apparait-il que parce qu'il manque un mot dans la définition de ta classe Network, car, peut etre devrait elle être "fournir un mapping des serveurs actifs".

    Tu te rendrais alors compte que, s'il est nécessaire, pour l'exécution de ton programme, d'avoir une liste de serveurs actifs, il est tout aussi nécessaire d'avoir une liste de serveur potentiels (comprend : que l'on peut essayer de contacter afin de mettre la connexion en place).

    Cette liste de serveur potentiels pourrait venir de n'importe où, mais on peut envisager la simple utilisation d'un fichier ini (ou autre) qui listes les serveurs qui étaient connus à l'exécution précédente par exemple, ou l'utilisation de la base de registre pour les enregistrer.

    Et tu pourrais meme, pourquoi pas, envisager de parcourir toutes les ip correspondant au réseau jusqu'à ce que tu en trouves une qui corresponde à un serveur actif, mais bon...

    Ce qui importe, surtout, c'est de ne pas dépendre de ta classe Network (et de sa liste de serveurs) afin de pouvoir mettre ta connexion en place

    Le seul moyen d'y arriver, c'est de fournir un liste d'ip que ton application peut essayer de contacter

    En fonction de ton projet, de tes impératifs de sécurité, c'est à toi de voir quelle est la meilleure (ou du moins la moins mauvaise) solution pour arriver à fournir cette liste
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  19. #19
    Membre Expert

    Avatar de germinolegrand
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Octobre 2010
    Messages
    738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Octobre 2010
    Messages : 738
    Par défaut
    Etant donné que par réseau, j'entends réseau virtuel formé par tous les serveurs, je vais avoir du mal à tester toutes les ip d'internet

    Pour avoir une liste de serveurs actifs (bien que je n'en vois pas l'intérêt) il suffit de faire une requête dans ce but sur le réseau et de compter les réponses ^^. J'aimerais éviter au possible d'avoir à connaitre tous les serveurs.

    Et pour maintenir une connexion il suffit d'une seule chose : un sf::TcpSocket.

    En fait je me demande si ConnexionService et Network ne sont pas une seule et même classe...

  20. #20
    Membre Expert

    Avatar de germinolegrand
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Octobre 2010
    Messages
    738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Octobre 2010
    Messages : 738
    Par défaut
    Tout ça est bien beau mais on s'éloigne du sujet
    screetch donne un élément de réponse que je trouve très intéressant :
    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
    class Network
    {
    public:
        Network(sf::IpAddress join);
        Network(const Network&) = delete;
     
        virtual ~Network();
     
    private:
         // ATTENTION, les initialisations sont faites dans l'ordre
         // de leurs declarations dans la classe, donc mettre le
         // champ modifiable en premier
         std::map<ServerId, std::unique_ptr<sf::TcpSocket>> m_otherServers;
         const ServerId m_id = 1;
     
         static ServerId doConnectToIP(std::map& serverList, sf::IpAddress join);
    };
     
    Network::Network(sf::IpAddress join)
     : m_otherServers()
     , m_id(doConnectToIP(m_otherServers, join)
    {
    }
    Je pense donc que je vais adapter ça à ma sauce, en modifiant quelque peu mon architecture (notamment en faisant un héritage multiple entre ConnexionService, Network, et Service).

Discussions similaires

  1. [XSLT][JSP] solution technique pour cas typique
    Par Alix_10 dans le forum XSL/XSLT/XPATH
    Réponses: 3
    Dernier message: 04/09/2006, 13h09
  2. Chaines et pointeurs mais pas "const"
    Par hpfx dans le forum C
    Réponses: 9
    Dernier message: 05/10/2003, 20h23
  3. [SYBASE] INFO AU CAS OU...
    Par Zeo_BO dans le forum Sybase
    Réponses: 6
    Dernier message: 29/07/2003, 12h44
  4. [corba] débutant : dans quels cas l'utiliser
    Par jmturc dans le forum CORBA
    Réponses: 2
    Dernier message: 10/10/2002, 08h58

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