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 :

Serialisation portable d'obj connu


Sujet :

C++

  1. #21
    Membre confirmé
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2005
    Messages
    87
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2005
    Messages : 87
    Par défaut
    Je viens de commencer à coder et le problème des templates me rattrape encore :/ Sale crasse ce truc sur un vieux g++
    Serialize.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
    #ifndef SERIALIZE_MAIN_
    #define SERIALIZE_MAIN_
    #include "iostream.h"
    #include "stdlib.h"
    #include "fstream.h"
    class Serialize
    {
        public:
            Serialize(const char * nomFichier, int tailleSegment=0);
            template <class B> void operator<<(const B & b)
            {
                cerr<<"Operateur d'insert"<<endl;
            }
        private:
            int _tailleSegment;
            Serialize();
    };
    #endif
    Serialize.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #include "Serialize.h"
    Serialize::Serialize(const char * nomFichier, int tailleSegment)
    {
        cerr<<"[SERIALIZE] Constructeur"<<endl;
    }
    Mais mon prof ne trouve vraiment pas ça joli d'avoir une fonction implémentée dans un .h... seule fonction template de tout ma classe

    J'essaye ceci:
    Serialize.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
    #ifndef SERIALIZE_MAIN_
    #define SERIALIZE_MAIN_
    #include "iostream.h"
    #include "stdlib.h"
    #include "fstream.h"
    class Serialize
    {
        public:
            Serialize(const char * nomFichier, int tailleSegment=0);
            template <class B> void operator<<(const B & b);
        private:
            int _tailleSegment;
            Serialize();
    };
    #endif
    Serialize.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #include "Serialize.h"
    Serialize::Serialize(const char * nomFichier, int tailleSegment)
    {
        cerr<<"[SERIALIZE] Constructeur"<<endl;
    }
    template <class B>
    void Serialize::operator<<(const B & b)
    {
        cerr<<"[SERIALIZE] <int> Operateur d'insertion"<<endl;
    }
    //Problème ici !!
    template void Serialize::operator<<(const int & b);
    Mais je suis obliger d'instancier mes templates ainsi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    template void Serialize::operator<<(const int & b);
    Car sinon mon main me répond:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    undefined reference to `void Serialize::operator<< <int>(int const&)
    C'est moche ... quel est l'interet des templates alors ?
    Comment concerver la séparation .h/.cpp
    sachant que le compilateur que j'ai à l'école est incapable de faire de l'instentiation automatique... donc il compile le template et puis arriver au main il ne va plus voir le template qui est compilé une seule et unique fois et se crache comme un c** à l'édition des liens. Je par à la recherche d'un mécanisme de manière à forcer une recompilation...

  2. #22
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 399
    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 399
    Par défaut
    Dis à ta prof de revoir sa copie, une fonction template est toujours définie dans un .h.

    Ou dans un fichier à part (l'extension .tpp semble populaire) inclus par le .h.
    Il ne peut en être autrement à moins d'utiliser les export templates, qui ne sont pas supportés partout pareil.
    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.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Et, de manière générale, évite les fichiers d'en-tete standard avec l'extension .h...

    Préfère leur la version sans extension, qui t'assure qu'ils prennent en compte - bien qu'à leur manière - la norme
    Utilise donc de préférence
    • <iostream> pour remplacer iostream.h
    • rien (pas besoin) pour remplacer stdlib.h
    • <fstream> pour remplacer fstream.h


    La simple différence réside dans le fait que les différentes classes déclarées dans ces fichiers sont accessibles dans l'espace de noms std
    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

  4. #24
    Membre confirmé
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2005
    Messages
    87
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2005
    Messages : 87
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Et, de manière générale, évite les fichiers d'en-tete standard avec l'extension .h...

    Préfère leur la version sans extension, qui t'assure qu'ils prennent en compte - bien qu'à leur manière - la norme
    Utilise donc de préférence
    • <iostream> pour remplacer iostream.h
    • rien (pas besoin) pour remplacer stdlib.h
    • <fstream> pour remplacer fstream.h


    La simple différence réside dans le fait que les différentes classes déclarées dans ces fichiers sont accessibles dans l'espace de noms std
    Ca je savais :p mais j'ai pas trop envie de m'amuser avec le namespace std pour li'nstant. Avec ou sans extension quel sont les réels changement ? car la majorité des EDI sont capable de faire des groupage de fichier suivant extension que je trouve bien pratique. Le fait d'avoir l'extension permet aussi de savoir ce qu'il y a dedans. Pourquoi la version sans extension respecte plus la "norme" ?
    Citation Envoyé par Médinoc Voir le message
    Dis à ta prof de revoir sa copie, une fonction template est toujours définie dans un .h.

    Ou dans un fichier à part (l'extension .tpp semble populaire) inclus par le .h.
    Il ne peut en être autrement à moins d'utiliser les export templates, qui ne sont pas supportés partout pareil.
    A bon ?! Moi qui croyais pourtant qu'il serait possible de définir une fonction template membre dans la classe et de l'implémenter dans le .cpp correspondant.
    J'ai essayé la version ".tpp" comme tu appeles ça. J'ai utilisé le modèle de la FAQ ... et je ne sais pourquoi mais dans mon cas, ça ne marche pas. Il faut que seul la fonction membre soit dans ce fichier ? Donc ça me ferais 2fichier par classe + autant de fichier que de fonction membre. Exact ?

    Pour en revenir à des librairies existantes dont je suis censé m'inspirer "intelligemment" savez vous comment elles gèrent les templates ? (boost & stl)

    Encore merci de partager vos connaissance qui nous sont utile pour parfois combler le manque de précision dans nos syllabus !

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Citation Envoyé par Haknaton Voir le message
    Ca je savais :p mais j'ai pas trop envie de m'amuser avec le namespace std pour li'nstant. Avec ou sans extension quel sont les réels changement ? car la majorité des EDI sont capable de faire des groupage de fichier suivant extension que je trouve bien pratique. Le fait d'avoir l'extension permet aussi de savoir ce qu'il y a dedans. Pourquoi la version sans extension respecte plus la "norme" ?
    En fait, la version avec l'extension a été utilisée de manière propre à chaque compilateur avant qu'il n'y ait l'idée d'une normalisation.

    Pour éviter les problèmes de compatibilité et d'ambiguité (un truc qui serait déclaré dans un fichier d'en-tête sur un compilateur particulier et dans un autre sur un autre compilateur) la norme a décidé de n'utiliser aucune extension, et de tout mettre dans un espace de noms particulier

    Finalement, qu'il s'agisse de la version avec ou sans extension, tu peux toujours ouvrir le fichier d'en-tete avec n'importe quel éditeur de texte... La seule différence se retrouvant sous windows où, ne disposant pas d'extension, il est impossible de demander à windows de décider automatiquement l'outil à utiliser pour les ouvrir

    Quant à l'utilisation de l'espace de nom std en elle-même, il "suffit" de prendre l'habitude d'utiliser le nom long (std::cout, std::string, ...) au lieu de la version abrégée (cout, string, ...)... Et encore, en dehors des fichiers d'en-tête, rien ne t'interdit d'utiliser la directive using namespace, bien que cela enlève tout l'attrait des espaces de noms, du fait que tu ne saura plus faire la différence entre la classe vector de la STL et ta propre classe vector
    A bon ?! Moi qui croyais pourtant qu'il serait possible de définir une fonction template membre dans la classe et de l'implémenter dans le .cpp correspondant.
    J'ai essayé la version ".tpp" comme tu appeles ça. J'ai utilisé le modèle de la FAQ ... et je ne sais pourquoi mais dans mon cas, ça ne marche pas. Il faut que seul la fonction membre soit dans ce fichier ? Donc ça me ferais 2fichier par classe + autant de fichier que de fonction membre. Exact ?
    Le principe d'une classe (ou fonction) template, c'est que l'on y indique tout sauf... le type d'objet réellement géré.

    Du coup, le compilateur ne peut pas crééer un implémentation réelle du code des différentes fonctions, vu qu'il ne sait pas... quelle taille donner à l'objet.

    Il ne créera le code propre à un type particulier qu'une fois qu'il saura... quel type est à utiliser, et donc sa taille en mémoire

    Mais pour pouvoir créer le code "exécutable" de la fonction, il faut qu'il soit en mesure... de trouver le code C++ de cette fonction, et donc, que cette implémentation soit accessible par le fichier d'en-tête.

    Comme il est généralement admis que les fichier ayant l'extension cpp sont des fichier d'implémentation qui sont de nature à permettre la création d'un fichier objet, il est également admis "l'interdiction" d'inclure un fichier de cette extension avec la directive #include

    C'est la raison pour laquelle le meilleur conseil à donner est, si tu ne veux pas présenter l'implémentation d'une fonction (méthode) template directement dans le fichier d'en-tête, d'utiliser une extension de ton choix autre que cpp ou toute extension communément admise pour représenter un type de fichier particulier (xml, jpg, htm...)

    C'est la raison pour laquelle on propose régulièrement tpp (Template cPP) impl (IMPLementation) ou autre
    Pour en revenir à des librairies existantes dont je suis censé m'inspirer "intelligemment" savez vous comment elles gèrent les templates ? (boost & stl)
    en un mot: incontournable.

    Tout (ou presque) passe par l'utilisation de template, tant dans boost que dans la stl.

    Quant à la manière dont c'est implémenté, cela peut très bien varier entre la définition de la fonction directement dans la déclaration de la classe et l'implémentation dans un fichier particulier (tpp, impl ou... n'importe quoi tant que ce n'est pas un *.cpp ou une des extensions régulièrement admise pour représenter un type de fichier particulier)
    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

  6. #26
    Membre confirmé
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2005
    Messages
    87
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2005
    Messages : 87
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Dis à ta prof de revoir sa copie, une fonction template est toujours définie dans un .h.

    Ou dans un fichier à part (l'extension .tpp semble populaire) inclus par le .h.
    Il ne peut en être autrement à moins d'utiliser les export templates, qui ne sont pas supportés partout pareil.
    Je parlais bien de l'implémentation! qui malheureusement doit être faite dans le .h afin de ne pas devoir instancer manuellement les templates

  7. #27
    Membre confirmé
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2005
    Messages
    87
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2005
    Messages : 87
    Par défaut
    Question pour les amateurs de boost.

    Comment boost détecte t'il que la taille de la chaine qu'il va désérialiser si on lui passe un char * ?
    Car je suis callé sur ce point et j'hésite à lire tout char par char jusque arriver au 0 de fin de chaine ... serait t'il possible d'utiliser la lecture avec un fstream jusqu'un délimiteur ?

  8. #28
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Par défaut, boost ne sérialise pas les char*, c'est trop casse gueule (surtout à la désérialisation : La mémoire doit-elle être allouée par new, par malloc, par autre-chose, ne pas être allouée,... ?).

    Pour les chaînes string, de mémoire, il sauve d'abord la taille, puis la chaîne.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  9. #29
    Membre confirmé
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2005
    Messages
    87
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2005
    Messages : 87
    Par défaut
    Merci de la réponse JolyLoic
    J'ai donc pris une décision. On nous a cassé les pieds pour qu'on utilise des char* je sauvegarderais donc des char * et puis je ferais des new.
    Et comme il est facile de distinguer char * et const char* je sais où je dois faire des strcpy et où je dois faire des new.

    edit: ouich, comme l'histoire du serpent qui se mort la queue...


    Détecter un tableau en const char* c'est bien ... mais une fois que j'ai lu ce que je devait récupérer dans le fichier pour faire une désérialisation, comment faire un strcpy sur un const char* ....

    Je patauge...

    ------------------------------------------------------------
    J'ai testé avec des casts barbares de (char*) ... c'est puant, ça à marché (30sec) pour les tableau. Qd j'ai du passer aux chaines dynamique je me suis rendu compte que je devait jouer avec des pointeurs de pointeurs... (double free sinon)

    Impossible de faire du bon travail sans de bon outils. Avec string ça aurait fonctionné ... mais bon les prof veulent que l'on soit au courant des mécanismes internes du cpp (char* + allocation dynamique) et pas de string. Moi qui voulait avoir une super librairie, je dépose les armes.

    Direction le délestage du forum ...
    Histoire d'un étudiant rebelle ou perfectionniste :/ ?

Discussions similaires

  1. Comment faire un Timer de fonction PORTABLE ?
    Par dieuP1guin dans le forum C
    Réponses: 3
    Dernier message: 04/07/2003, 11h44
  2. Delphi7 winxp pro renvoyer un TLabel connu par nom
    Par regis1_1 dans le forum Composants VCL
    Réponses: 3
    Dernier message: 18/06/2003, 12h09
  3. Code Portable
    Par D[r]eadLock dans le forum C
    Réponses: 9
    Dernier message: 14/09/2002, 14h44
  4. [Migratation] Application portable, indépendant du SGDB
    Par benouille dans le forum Décisions SGBD
    Réponses: 6
    Dernier message: 28/08/2002, 14h51
  5. Choix d'un EDI pour la 3D (Open GL, Portable)
    Par Riko dans le forum OpenGL
    Réponses: 6
    Dernier message: 01/08/2002, 13h25

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