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 :

Ajouter une en-tete à un ostream


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    37
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 37
    Par défaut Ajouter une en-tete à un ostream
    Bonjour,

    Je vous ecrit car j'essaye de developper une classe proprement (pour une fois) dans laquelle je donne au constructeur un parametre de type "ostream&" avec cout comme parametre par defaut histoire de pouvoir rediriger par la suite tous les messages de ma classe vers le flux que je veux (un fichier de log à la place de la sortie standard par exemple).

    Voici en exemple le constructeur simplifié avec vous l'aurez compris les deux données membres declarées precedemment en private dans la classe :

    CCamera(int indexCam, std::ostream& stream=std::cout)
    : m_stream(stream),
    m_indexCam(indexCam)
    {}
    Ceci fonctionne parfaitement et j'ecris tous mes message sous la forme :

    m_stream << "exemple sortie" << std::endl;
    Maintenant j'ai un peu reflechi et j'aimerai faire quelques chose de mieux. Je m'explique : je voudrais que, a chaque fois que j'utilise mon "m_stream", il se rajoute en en-tete du message que je vais rediriger, un message identifiant d'ou vient le message.

    En clair j'aimerais que pour cette classe camera qui sera instanciée avec indexCam=N par exemple, quand j'utilise la ligne de code precedente, au lieu d'avoir dans mon flux : "exemple sortie" j'ai quelques chose du style : "CAMERA N : exemple sortie"

    J'ai pensé a creer une classe CMyStream et à redefinir l'operateur << mais je ne sais pas vraiment comment m'y prendre.

    Dois-je deriver ma classe de ostream histoire de pouvoir prendre avantage de toutes le fonctions membres existantes deja ?

    Dois plutot juste faire une classe basique sans forcement deriver de ostream ?

    Bref si vous avez des conseils concernant ce type de besoin ou une piste a explorer je vous en serait reconnaissant :-)

    Merci de votre aide à bientot !!!

  2. #2
    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
    Salut, et bienvenue sur le forum

    Typiquement, tu peux faire appel à tout membre quelqu'en soit la visibilité, dans le constructeur de ta classe, pour autant :
    • que ce ne soit pas un membre privé de la classe parent (dans le cadre d'un héritage)
    • que ce ne soit pas un membre d'une classe enfant (dans le cadre d'un héritage)
    Si, donc, tu dispose d'un membre nommé "numero" ou "id", par exemple dans ta classe camera et permettant d'identifier une caméra parmi d'autres, tu pourras envisager l'écriture d'un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    stream<< "ceci est la camera "<<numero
          <<" et son exemple de constructeur";
    pour autant que l'opérateur << existe pour le type de numero (ce qui est le cas pour l'ensemble des types primitifs)...

    Tout ce à quoi il te faudra veiller, c'est à ce que le membre en question soit correctement initialisé avant d'essayer d'en envoyer la valeur dans le flux
    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

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    37
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 37
    Par défaut
    Salut,

    Merci pour ta reponse rapide mais ma question ne concernait pas l'insertion de ma donnée membre dans le flux ce qui n'est effectivement pas un probleme.

    Desolé pour mon message un peu long qui doit etre un peu confus mais il s'agirait en fait de definir un nouveau flux (comme le cout utilisé courrament) qui ajouterais une en tete à tous les messages que j'enverrai dans le flux.

    Est-ce possible ? Je me doute que oui mais je ne sais pas trop comment aborder la question...

    Merci :-)

  4. #4
    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
    Hé bien, selon le cas, tu peux envisager une fonction libre / statique de classe / particulière dans une classe donnée dans laquelle tu crées toi-même l'en-tête de ton flux...

    Une fonction libre peut prendre une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    /* voici une fonction libre renvoyant un flux de sortie
     * @in none
     * @out objet de type ostream
     *
     * !!! le flux étant créé dans la fonction, il doit être renvoyé par valeur
     * et non par référence, ce qui  implique une copie de l'objet si le compilateur
     * ne supporte pas (N)RVO
     */
    std::ostream createStream()
    {
        std::ostream os;
        os<<"Ceci sera l'en-tête du flux"<<std::endl;
        return os;
    }
    Dans une classe, cela pourrait prendre la forme d'une fonction statique proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class MyClass
    {
        public:
        /* fonction statique permettant de rajouter l'en-tête
         * dans n'importe quel flux existant
         */
        static void createHeader(std::ostream& os)
        {
            os<<"Ceci sera l'en-tête du flux"<<std::endl;
        }
    };
    Enfin, tu pourrais envisager d' "encapsuler" le flux en tant que membre d'une classe, et de créer l'en-tête au niveau du constructeur de cette classe
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    class MyFileWriter
    {
        public:
            MyFileWriter(std::string const& f):filename_(f),os(f.c_str())
            {
                os<<"Ceci  sera l'en-tête du flux (qui  est un fichier ici)"
                  <<std::endl;
            }
            std::ofstream& stream(){return os;}
            std::string filename() const{return filename_;}
        private:
            std::string filename_;
            std::ofstream os;
    };
    Et ce ne sont bien sur que les premières idées qui m'ont traversé l'esprit
    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

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    37
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 37
    Par défaut
    Rebonjour,

    Ok je comprends ce que tu veux dire (bien que la syntaxe du dernier exemple ne me soit pas familiere) ;-)

    Or j'imagine que tes exemples sont la pour creer un flux et/ou ecrire dedans lors de la premiere utilisation.

    J'aurais voulu avoir en fait dans la classe que je vais utiliser (mais peut importe que soit une classe ou non) une donnée membre que je puisse utiliser comme le classique "cout".

    A savoir qu'il me rajoute cette fameuse en tete a chaque fois que j'utilise le flux.

    Voici ce que j'ai fait pour l'instant mais qui bien sur ne compile pas, c'est juste pour te montrer l'esprit :

    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
     
    class CMyStream
    {
        private:
     
    	string m_header;
    	ostream& m_stream;
     
    	string m_spacing;
     
        public:
     
    	CMyStream(string header, ostream & stream=cout, string spacing=string(" "))
    	:m_header(header),
    	 m_stream(stream),
    	 m_spacing(spacing)
    	{}
     
    	~CMyStream() {};
     
    	ostream& operator<<(ostream & streamIN)
    	{
    		return m_stream << m_header << m_spacing << streamIN;
    	}
    };
    Le but est de pouvoir utiliser une instance de cette classe comme le "cout" habituel.

    cad :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    monInstanceDeCMyStream << "test" << endl;
    et que lors de l'affichage il me rajoute au debut le contenu de m_header.

    Le probleme quand je fais ca est que bien sur à chaque fois que j'essaye d'utiliser l'operateur << avec un type de base il m'envoie bouler en me disant que ma fonction candidate est la fonction membre definie mais que la conversion n'est pas possible.

    J'ai essayé de fire deriver cette classe de la classe ostream mais sans succès (probleme de constructeur private j'imagine)...

    J'ai peut etre du mal a etre clair dsl

  6. #6
    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 : 50
    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
    Ce genre de chose se fait généralement en dérivant du streambuffer. Mais il existe un framework pour manipuler ainsi les flux plus aisément : http://www.boost.org/doc/libs/1_39_0...doc/index.html
    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.

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    37
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 37
    Par défaut
    Merci beaucoup pour cette piste,

    apres un peu de temp passé à rechercher sur notre moteur de recherche préféré et m'etre perdu dans beaucoup de lignes de codes non commentées et non expliquées j'ai fini par trouver ca :
    http://savingyoutime.wordpress.com/2...logging-class/

    Ceci semble correspondre tout a fait a ce que je recherche, je vais essayer de comprendre et de jouer avec cet exemple et voir si j'arrive à faire ce que je voulais. Je vous tiendrai au courant.

    Si vous avez des remarques a faire quand au contenu de ce lien, ca serait avec plaisir.

    Merci encore et @ bientot j'espere !

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

Discussions similaires

  1. Réponses: 0
    Dernier message: 01/08/2013, 16h08
  2. Réponses: 0
    Dernier message: 17/01/2012, 15h54
  3. [C#] ajouter une image dynamiquement
    Par h_imane dans le forum ASP.NET
    Réponses: 4
    Dernier message: 21/04/2004, 11h27
  4. [Plugin] Ajouter une option au menu contextuel ?
    Par relivio dans le forum Eclipse Platform
    Réponses: 2
    Dernier message: 22/03/2004, 16h18
  5. Ajouter une aide
    Par Mailgifson dans le forum C++Builder
    Réponses: 5
    Dernier message: 12/06/2002, 13h32

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