Problème avec operator

Le
C++
Bonjour à tous.
Je dispose du code suivant:

//
//deco.h
//INFO: je sais que le code est pas super propre mais c'est pas grave ;D

#include <string>
#include <iostream>

class Composant
{
protected:
double m_prix;
std::string m_name;
public:
virtual int GetPrix() const {return m_prix;}
virtual std::string GetName() const {return m_name;}

virtual ~Composant(){}
};

class Crepe: public Composant
{
public:
Crepe();
};

class Gauffre: public Composant
{
public:
Gauffre();
};

class Decorateur : public Composant
{
public:
virtual int GetPrix(){return (m_compo.GetPrix()+m_prix);}
virtual std::string GetName(){return (m_compo.GetName()+" "+m_name);}
protected:
Composant& m_compo;
Decorateur(Composant& compo);
};


class Sucre : public Decorateur
{
public:
Sucre(Composant& compo);
};

class Nutella : public Decorateur
{
public:
Nutella(Composant& compo);
};

template <class T> std::ostream & operator << (std::ostream & flux,const
T& t)
{

flux<<t.GetName()<<" : "<<t.GetPrix()<<std::endl;
return flux;
}
//-
//deco.cpp
#include "deco.h"

using namespace std;

Crepe::Crepe(){m_prix=1.5;m_name="Crepe maison";}
Gauffre::Gauffre(){m_prix=1;m_name="Gauffre maison";}

Decorateur::Decorateur(Composant& compo):m_compo(compo){}

Sucre::Sucre(Composant&
compo):Decorateur(compo){m_prix=0.2;m_name="Sucre";}
Nutella::Nutella(Composant&
compo):Decorateur(compo){m_prix=0.5;m_name="Nutella";}

int main(int argc,char* argv[])
{
Crepe c;
//cout<< c;//ligne a problème
}

Tout le code compile très bien si la ligne a problème est commenté
Mais si cette ligne est décomenté, elle donne les erreurs suivantes:
deco.h: In function ‘std::ostream& operator<<(std::ostream&, const T&)
[with T = Crepe]’:
deco.cpp:16: instantiated from here
deco.h:54: error: ambiguous overload for ‘operator<<’ in ‘flux <<
#‘obj_type_ref’ not supported by dump_expr#<expression error>()’
deco.h:51: note: candidates are: std::ostream& operator<<(std::ostream&,
const T&) [with T = std::string]
/usr/include/c++/4.2/bits/basic_string.h:2400: note:
std::basic_ostream<_CharT, _Traits>&
std::operator<<(std::basic_ostream<_CharT, _Traits>&, const
std::basic_string<_CharT, _Traits, _Alloc>&) [with _CharT = char, _Traits
= std::char_traits<char>, _Alloc = std::allocator<char>]


Je pense que cela vient de la facon d'appeler << mais je n'ai _aucune
idée_ pour le résoudre.
Merci beaucoup.

David Côme
Vos réponses
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Sylvain
Le #313181
C++ wrote on 09/12/2007 14:02:
Bonjour à tous.
Je dispose du code suivant:

#include <string>
#include <iostream>

class Composant {
protected:
double m_prix;
std::string m_name;
public:
virtual int GetPrix() const {return m_prix;}
virtual std::string GetName() const {return m_name;}
virtual ~Composant(){}
};


donc (vraisemblablement) une gestion des particularité par un
polymorphisme dynamique (ie un héritage et spécialisation).

class Crepe: public Composant {
public:
Crepe();
};
class Gauffre: public Composant {
public:
Gauffre();
};


ces classes semblent inutiles, les traits spécifiques sont les valeurs
de champs définis par la classe de base, non le fait d'avoir une classe
nommée.

les définitions (en supposant un constructeur idoine à Composant):

Composant crepe("Crepe maison", 1.5);
Composant gauffre("Gauffre maison", 1.0);

permettaient le même résultat sans multiplication des classes.

class Decorateur : public Composant {
public:
virtual int GetPrix(){return (m_compo.GetPrix()+m_prix);}
virtual std::string GetName(){return (m_compo.GetName()+" "+m_name);}
protected:
Composant& m_compo;
Decorateur(Composant& compo);
};


même remarque: les attributs hérités ne sont pas définis à ce niveau,
l'héritage (Sucre et Nutella) seront nécessaires, non comme une
spécialisation utile mais comme le seul moyen de définir le substrat de
la recette.

template<class T> std::ostream& operator<< (std::ostream& flux,const T& t)
{
flux<<t.GetName()<<" : "<<t.GetPrix()<<std::endl;
return flux;
}


ici un polymorphisme statique (par template), pourquoi ce mélange ?

si vous définissez dans Composant:

friend ostream& operator<< (ostream& flux, const Composant& t){
return (flux << t.GetName() << " : " << t.GetPrix() << std::endl);
}

vous obtiendrez directement le service attendu (sans génération des
fonctions templates).

Sylvain.

David Côme
Le #313180
Je sais que l'architecture globale de mon exemple n'est pas bonne.
C'est disons a un 1er jet a grandement amélioré.

Sinon pour le vrao problème en soit, je me demande toujours pourquoi j'ai
voulu passer par les templates.

Merci beaucoup.

David Côme
Franck Branjonneau
Le #313142
C++
class Composant
{
public:
virtual int GetPrix() const {return m_prix;}
virtual std::string GetName() const {return m_name;}

};


class Decorateur : public Composant
{
public:
virtual int GetPrix(){return (m_compo.GetPrix()+m_prix);}
virtual std::string GetName(){return (m_compo.GetName()+" "+m_name);}
protected:
};


Manque pas des const ?

--
Boujou
Franck

David Côme
Le #313141
Si mais ceux la je les ai vu après ><.
Maintenant tout compile et marche très bien.

Merci.
Publicité
Poster une réponse
Anonyme