jex0519
Messages postés10Date d'inscriptionjeudi 27 septembre 2007StatutMembreDernière intervention 9 décembre 2008
-
5 déc. 2008 à 09:59
Polack77
Messages postés1095Date d'inscriptionmercredi 22 mars 2006StatutMembreDernière intervention22 octobre 2019
-
9 déc. 2008 à 12:56
Bonjour à tous,
Je suis débutant en c++, et j'ai un projet ou je dois sauvegarder mes objets afin de pouvoir les recharger après...
Je voulais savoir comment celà ce passe en C++ pour la sérialisation d'objet??
Merci d'avance!
voici un exemple de mes classes:
class Administrateur : public Personne
{
public:
// class constructor
Administrateur(string nom, string prenom, string username, string password);
virtual void affiche();
// class destructor
~Administrateur();
};
-----------------------
class Equipe
{
// class destructor
~Joueur();
};
----------------------
class Match
{
private:
Equipe *domicile;
Equipe *exterieure;
int scoreEquipeA, scoreEquipeB;
public:
// class constructor
Match(Equipe *d,Equipe *e, int scoreEquipeA, int scoreEquipeB);
// class destructor
Equipe* getDomicile(){return domicile;}
Equipe* getExterieure(){return exterieure;}
int getScoreEquipeA(){return scoreEquipeA;}
int getScoreEquipeB(){return scoreEquipeB;}
~Match();
};
--------------------------
class Personne
{
Polack77
Messages postés1095Date d'inscriptionmercredi 22 mars 2006StatutMembreDernière intervention22 octobre 20191 5 déc. 2008 à 11:01
Salut ,
Alors la serialisation en Dot.Net c'est tout simple (perso du coup je n'es plus le moindre ini dans mes dév. Je sauvegarde mes config/obj/... avec la serialisation )
Petite explication : Pour faire de la serialisation il faut plussieur chose :
-> 1ér étape note tes objet comme seralisable (<Serializable()> en début de déclaration de tes structure/classe)
-> Sauvegarde d'un objet seralisable :
-> ouvre un stream fichier (System.IO.FileStream)
-> Cree un serialiseur (System.Runtime.Serialization.Formatters.Binary.BinaryFormatter)
-> Ecit dans le fichier
-> Lecture d'un fichier serialisé
-> ouvre un stream fichier (System.IO.FileStream)
-> Cree un serialiseur (System.Runtime.Serialization.Formatters.Binary.BinaryFormatter) (Sa me rapel un truc )
De petit exemple VB.NET et strucure mais tres simple à traduire (fonctionement identique pour une classe): Déclaration de la structure (ou classe)
<Serializable()> Public Structure S_ConfigGenerale
Public DossierDonnees As String
'[...]
End Structure
Déclaration de l'objet à serialisé (rien de particulier en faite ici )
Public ConfigGenerale as S_ConfigGenerale
Fonction de sauvegarde :
Public Sub SauveConfig()
Dim AccesseurAuFichier As New System.IO.FileStream("C:\NomDuFichierDeSauvegade.sav", IO.FileMode.OpenOrCreate)
Dim Formateur As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
Formateur.Serialize(AccesseurAuFichier, ConfigGenerale)
AccesseurAuFichier.Close()
End Sub
Fonction de lecture :
Public Sub LoadConfig()
Dim AccesseurAuFichier As New System.IO.FileStream("C:\NomDuFichierDeSauvegade.sav", IO.FileMode.Open)
Dim Formateur As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
ConfigGenerale = Formateur.Deserialize(AccesseurAuFichier)
AccesseurAuFichier.Close()
End Sub
Voila avec sa tu ne peut pas avoir encore des problèmes de serialisation (par contre à tu réelement cherché des tuto sur ce site av de possé cette question ??? Je suis sur que non, et c'est MAL !!!!! )
PS : Tu peut serialisé plussieur objet dans le même ficheir.
Ex :
Public Sub SauveConfig()
Dim AccesseurAuFichier As New System.IO.FileStream("C:\NomDuFichierDeSauvegade.sav", IO.FileMode.OpenOrCreate)
Dim Formateur As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
Polack77
Messages postés1095Date d'inscriptionmercredi 22 mars 2006StatutMembreDernière intervention22 octobre 20191 5 déc. 2008 à 12:22
Heeeeeee cela répond t'il à ta question ?
Si oui pense réponse acceptée (cela permettras à d'autre qui se pose la même question de trouvé la réponse plus facilement .
Si non te reste t'il des questions (sur le même sujet par contre ) ?
Tiens, je remarque que il n'y à pas de tuto sur la sérialisation dans cppfrance ????? Désolé pour ma remarque j'étais certain du contraire (mais une tite rechérche dans Google t'aurais permit de trouvé tout de suite , deux gros avantages : en générale les réponses sont plus précises et tu n'a pas à attendre d'éventuel réponse qui parfais n'arrive jamais en plus . J'ai recherché dans Google "sérialisation c#" et 1ér réponse : ici, ce tuto est même plus péris que ma réponse )
jex0519
Messages postés10Date d'inscriptionjeudi 27 septembre 2007StatutMembreDernière intervention 9 décembre 2008 5 déc. 2008 à 15:06
LoL.. Oui j'avais fait des recherches sur google et sur cppfrance avant de faire ce poste évidement..
Mais malheureusement comme je suis un bon gros débutant je n'ai rien trouvé d'assez claire pour y comprendre quelque chose. C'est pourquoi j'ai créé ce poste, mais les exemples que tu me donnes en VB.NET et C# sont trop flous pour moi qui débute la programmation en C++. J'aurais besoin de quelque chose de plus claire et en C++...
Merci pour ton aide
Vous n’avez pas trouvé la réponse que vous recherchez ?
Polack77
Messages postés1095Date d'inscriptionmercredi 22 mars 2006StatutMembreDernière intervention22 octobre 20191 5 déc. 2008 à 16:17
Je n'es pas été claire
Haaaa......... Je vais faire mieux (déjà sa sera du C#, et du pas à pas)
Alors pour sérialisé un "truc" (objet, structure, ...) il faut plusieurs chose :
(1) Déjà il faut que tu note tes class comme sérialisable (sa on ne peut pas faire autrement). Il siffi d'ajouté "<Serializable()>" à la déclaration de ta classe. ATTENTION il faut que tu l'ajoute à TOUTE les déclaration (normalement VisualStudio retourne une erreur si tu en oublie )
Exemple :
[Serializable]
class Personne
{
//[...]
}
[Serializable]
class Administrateur : Personne
{
//[...]
}
Tiens pk avais tu ajouté "public" dans ces déclarations ????
(2) Il faut un "truc" qui te permet de lire/écrire dans un fichier. Pour cela on crée un objet "FileStream" (car c'est ce dont on à besoin pour la suite si non il existe aussi d'autre stream plus spécifique mais on ne les véra pas. C'est sans utilité ici)
Init de ton obj :
AccesseurFichier = new System.IO.FileStream("C:\\FichierSerialiser.dat",System.IO.FileMode.OpenOrCreate);
Pressions :
-> "C:\\FichierSerialiser.dat" est à remplacé par le nom du fichier dans le quel tu veut sauvegarder ton obj.
-> En C# les '\' doivent être doublé dans les chaine écrite en dur (soit direct dans le code prog).
-> Le mode d'ouverture correspond à ce que tu veut faire (ici ouvrir ou crée le fichier, on est plutôt dans un mode d'écriture du coup , pour lire il vaut mieux être en mode "System.IO.FileMode.Open" qui retourne une erreur si le fichier est abs, vue plus bas, pas de stress )
(3)
Ensuite il te faut un "truc" capable de transformé en une suite de nombre binaire l'objet que tu veut sérialisé. C'est la classe "BinaryFormatter" qui s'en charge (elle ne sait faire que sa, enfin je crois ). La même classe est utilisé pour re-transformé ta suite de valeur binaire en objet.
Init de l'obj :
Formatteur = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
Utilisation en sérialisation (pour cela j'admét qu'un obj Admin basé sur la classe administrateur à été déclaré, on utilise un FileStream pour l'acces au fichier (2) ) :
Formatteur.Serialize(AccesseurFichier, Admin);
Utilisation en Déserialisation (toujour pour ce même obj Admin) :
Admin = Formatter.Deserialize(AccesseurFichier);
Fin
Voila déjà on à passé en revue toute les spé
Maintenant un Exemple : Fonction d'écriture de deux obj dans un fichier (Admin et Perso) :
public Boolean SauveObjDansFichier (string
CheminFichier
,Administrateur Admin,Personne Perso)
{
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter Formatteur;
System.IO.FileStream AccesseurFichier = null;
try //<- Démarage de la gestion d'erreur (même si ici aucune erreur ne devrais se produire, sauf si par exemple on demande de crée en fichier en "g:" et que ce lecteur n'existe pas)
{
AccesseurFichier = new System.IO.FileStream(
CheminFichier
, System.IO.FileMode.OpenOrCreate); //ici OpenOrCreate car on écrit donc si le fichier n'existe pas on le cré
Formatteur.Serialize(AccesseurFichier, Admin);
Formatteur.Serialize(AccesseurFichier, perso);
AccesseurFichier.Close(); //Fini plus qu'à fermer le ficheir ;)
AccesseurFichier = null;
return true;
}
catch (Exception) //<- Le code passe ici en cas d'erreur
{
if (AccesseurFichier != null) //<- Si le fichier est encore ouvert on le ferme
(si non sa pourais possé des problèmes pour plus tard)
Fonction de lecture de ces même obj :
public Boolean LoadObjDepuisFichier(string CheminFichier, ref Administrateur Admin,ref Personne Perso)
{
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter Formatteur;
System.IO.FileStream AccesseurFichier = null;
try //<- Démarage de la gestion d'erreur
{
AccesseurFichier = new System.IO.FileStream(
CheminFichier
, System.IO.FileMode.Open); //Ici open car on lit donc on ne veut pas crée de fichier si il n'existe pas ;)
&Admin = Formatteur.Deserialize (AccesseurFichier);
&Perso = Formatteur.Deserialize (AccesseurFichier);
AccesseurFichier.Close(); //Fini plus qu'à fermer le ficheir ;)
AccesseurFichier = null;
return true;
}
catch (Exception) //<- Le code passe ici en cas d'erreur (le fichier n'existe pas par exemple)
{
if (AccesseurFichier != null) //<- Si le fichier est ouvert on le ferme (si non sa pourais possé des problèmes pour plus tard)
{
AccesseurFichier.Close;
}
return false;
throw;
}
}
Une petite présision pour cette fonction :
Cette fonction (Load...) utilise un passage par référance ce qui veut dire que si tu modifie Admin alors c'est en faite la variable passé que se voie modifier (identique à ByRef en VB.NET)
Voila je ne voie pas comment être plus claire si un point précis te pose encore problème demande je n'aurais plus le temps de refaire un truc complet
Polack77
Messages postés1095Date d'inscriptionmercredi 22 mars 2006StatutMembreDernière intervention22 octobre 20191 5 déc. 2008 à 16:20
Oups un oublie de trad du VB.NET au C# il faut lire :
Déjà il faut que tu note tes class comme sérialisable (sa on ne peut pas faire autrement). Il siffi d'ajouté "[Serializable]" à ...
Et non
Déjà il faut que tu note tes class comme sérialisable (sa on ne peut pas faire autrement). Il siffi d'ajouté "<Serializable()>" à ...
Polack77
Messages postés1095Date d'inscriptionmercredi 22 mars 2006StatutMembreDernière intervention22 octobre 20191 5 déc. 2008 à 16:43
Décidément c'est ma journée des oublies :
Si non tu à la possibilité de récup une version de Visual Stuido 2008 la :
http://msdn.microsoft.com/fr-fr/express/aa975050.aspx Normalement il est compatible au C++ et devrais pouvoir convertir automatiquement ton projet (je dit bien logiquement ce n'es pas parfait non plus, hélasse )
Si non sa devrais être possible en utilisant des tableau binaire que tu gére toi même :
Tu récup la taille de ton obj A L'OCTET PRÉS
Tu récup l'adresse de départ de ton obj (sa c'est facile ajoute simplement & avant le nom de ta variable)
De la tu traite sa comme une chaine de carac (Par contre ATTENTION si des octect sont à 0 alors les fonction tel que strcpy ne fonctionneront pas IL FAUT que tu utilise des fonction qui prenne en conte le nombre d'oct que tu envoie)
Ensuite tu écrit sa dans un fichier tél quel. Puis pour la lecture tu lit le fichier AU COMPLET et copie la valeur mémoire à l'adresse de ton obj (avec memecpy). Par contre tu devrais toi même gérer l'ensemble des erreurs éventuel, les versions de tes objet, la validité des données pour l'objet qui dois les recevoir ext si non de GROSSE surprise t'attende.
Si tu est débutant je te conseil vivement soit
-> de passé en C# si tu tiens à la sérialisation
-> de sauvegarder tes données dans des ".ini" (avec la notion de section et la possibilité de crée plusieurs fichiers si tu te débrouille bien c'est vraiment plus efficace que sa n'en à l'aire)
jex0519
Messages postés10Date d'inscriptionjeudi 27 septembre 2007StatutMembreDernière intervention 9 décembre 2008 5 déc. 2008 à 18:45
MDR Merci pour ce petit cours rapide de C# , malheureusement je suis étudiant et c'est un projet en C++ (dévellopé sous dev-cpp et Qt designer) donc je n'ai pas le choix du langage..
Je dois pouvoir sauvegarder des objets afin de les récupérer par la suite a l'ouverture du programme.
Je pensais que la méthode la plus simple était la sériallisation (car je l'ai utilisée en java) mais apparament en C++ il y a d'autres possibilitées et je ne sais pas laquelle est la mieux adaptée....
Je vais me renseigner sur les fichiers .ini et voir si c'est faisable...
Je ne suis pas au bout de mes peines je crois lol
Merci de tout le mal que tu t'es donnés quand même en tout cas
Polack77
Messages postés1095Date d'inscriptionmercredi 22 mars 2006StatutMembreDernière intervention22 octobre 20191 5 déc. 2008 à 23:12
Juste une petite question : Quel quantité de données ~ à tu à sauvegardé ?
Si juste des configurations : fichier ini parfaitement adapté (enfin de mon point de vue).
De grosse données : tu à le dois aux base de données (si oui je pense que sa peut être bien, rapide à faire, et relativement "classieux" pour ton rendu de projet , jette un coup d'œil ici le sql c'est le langage base de données) ?
Les deux : Les deux ?
jex0519
Messages postés10Date d'inscriptionjeudi 27 septembre 2007StatutMembreDernière intervention 9 décembre 2008 5 déc. 2008 à 23:39
La quantité de donnée n'est pas gigantesque et malheureusement le délai du projet ne me laisse pas le temps de m'interessé en plus au SQL déjà que Qt designer est assez complexe...
Je vais voir s'il est possible de sauvegarder mes objets, vectors et etc à l'aide des fichiers ini...
Polack77
Messages postés1095Date d'inscriptionmercredi 22 mars 2006StatutMembreDernière intervention22 octobre 20191 8 déc. 2008 à 09:54
Ok pas de problème. Tu tu change d'avis et que tu ne t'en sort pas post sur "http://www.sqlfr.com/" et envoie moi un MP je te filerais un ou deux tuyaux
Polack77
Messages postés1095Date d'inscriptionmercredi 22 mars 2006StatutMembreDernière intervention22 octobre 20191 8 déc. 2008 à 16:55
Je viens de pensé à un petit truc :
Les fichier ini (surtout avec les deux API que je t'es indiqué) on des problèmes pour stocker certaine valeur (surtout en cas de conversion de valeur numérique en chaine (prob de '\0') mais aussi avec les retour charriots). Pour contourné ce/s problème/s perso je passais par Base64.
[lien wiki lien wiki ]
Si tu fait le choix de tout stocké en ini je te conseil de passé systématiquement par ce genre de codage (pas forcément celui ci d'autre tout aussi adapté doivent existé) sa ne coute pas grand choses (en temps de traitement en tout cas, et l'espace disque ne coute plus très chère aujourd'hui). Par contre ATTENTION stockage non optimisé en taille les examinateurs pourraient être regardant la dessus (et du coup chiant ^^) à ton rendu de projet.
Fait également attention aux sorties de ta fonction Base64 (surtout si tu en récup une toute faite) des retours charriot son automatiquement inséré (ceux si n'ont aucune signification pour la re-traduction, donc supprime les purement et simplement, les ini ne supporte pas les retour charriots)
Polack77
Messages postés1095Date d'inscriptionmercredi 22 mars 2006StatutMembreDernière intervention22 octobre 20191 9 déc. 2008 à 12:56
N'hésite surtout pas à me faire un petit fet-back je pourrais peut être de données encore un ou deux conseil (pas forcément bon mais c'est pas grave tu feras le trie mdr).
A la rigueur crée un nouveau sujet dans le thème "Le bar / discutions libre"
Bonne prog (et bon courage pour ton projet c'est pas simple j'ai connue )