Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Problème avec operator

4 réponses
Avatar
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

4 réponses

Avatar
Sylvain
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.

Avatar
David Côme
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
Avatar
Franck Branjonneau
C++ écrivait:

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

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

Merci.