Aidez moi à éliminer les friend!!

Aidez moi à éliminer les friend!! - C++ - Programmation

Marsh Posté le 03-04-2008 à 14:53:57    

Aprés avoir lu une réponse de JoelF sur friend (il aime pas, moi non plus), je me suis dit que je pourrai peut-être éliminer définitivement mes opérateurs friend dans mon moteur de calcul (j'avais utilisé le Barton-Nackman trick, mais c'est peut-être inutile), donc voilà le problème, je veux créer des opérateurs sur des pointers qui pointent sur des objets différent mais ayant en commun un Functor sur lequel je veux opérer, le pire c'est que les objets sont templates, donc on a :

Code :
  1. class EQPDEProperty_Base{...};


 
Je définis une class SingleOperator pour mes Operator agissant sur un seul pointer (de classe X) me retournant un pointer (sur R):

Code :
  1. template<int INDEX_PDE, class X, class R>
  2. class EQSingleOperator : virtual public R, public with_type_traits<EQSingleOperator<INDEX_PDE,X,R> >
  3. {
  4. public:
  5.  using with_type_traits<EQSingleOperator<INDEX_PDE,X,R> >::sp;
  6.  using with_type_traits<EQSingleOperator<INDEX_PDE,X,R> >::const_sp;
  7.  typedef boost::function<double(double,double,double,AuxValues::sp,int)> Function;
  8.  EQSingleOperator(){}
  9.  EQSingleOperator(std::string sOperator, typename X::sp spX) : m_sOperator(sOperator), m_spX(spX), m_isPointer(true)
  10.  {
  11.   setStartDate(m_spX->getStartDate());
  12.   setEndDate(m_spX->getEndDate());
  13.   setType("("+m_sOperator+m_spX->getType()+" )" );
  14.   setPoints(m_spX->getPoints());
  15.   m_Evaluation = spX->get_functor();
  16.  }
  17.  virtual ~EQSingleOperator()
  18.  {};
  19.  typename X::sp getVar()
  20.  {
  21.   return m_spX;
  22.  }
  23.  std::string getOperator() {return m_sOperator;}
  24.  void setOperator(std::string sOperator) {m_sOperator=sOperator;}
  25.  void updateType()
  26.  {
  27.   setType("("+m_sOperator+m_spX->getType()+" )" );
  28.  }
  29.  inline Function getEvaluation(){return m_Evaluation;}
  30. private:
  31.  std::string m_sOperator;
  32.  typename X::sp m_spX;
  33.  Function m_Evaluation;
  34. };


 
Bon ensuite je fais une classe pour la multiplication par un double:
 

Code :
  1. template<int INDEX_PDE, class X, class R>
  2. class EQScalarMultProperty : virtual public EQSingleOperator<INDEX_PDE,X,R>, public with_type_traits<EQScalarMultProperty<INDEX_PDE,X,R> >
  3. {
  4. public:
  5.  using with_type_traits<EQScalarMultProperty<INDEX_PDE,X,R> >::sp;
  6.  using with_type_traits<EQScalarMultProperty<INDEX_PDE,X,R> >::const_sp;
  7.  EQScalarMultProperty(double dLambda,typename X::sp spX) : EQSingleOperator<INDEX_PDE,X,R>("",spX)
  8.  {
  9.   std::stringstream s;
  10.   s<<dLambda;
  11.   std::string sLambda = s.str();
  12.   std::string sOperator = sLambda;
  13.   sOperator += "*";
  14.   m_dLambda = dLambda;
  15.   setOperator(sOperator);
  16.   updateType();
  17.  }
  18.  virtual ~EQScalarMultProperty()
  19.  {};
  20.  virtual double evaluate(double dTime, double dPoint, double dValue, AuxValues::sp spAuxValues, int id)
  21.  {
  22.   Function eval = getEvaluation();
  23.   return eval(dTime,dPoint,dValue,spAuxValues,id)*m_dLambda;
  24.  }
  25.  virtual boost::function<double(double,double,double,AuxValues::sp,int)> get_functor()
  26.  {
  27.   return boost::function<double(double,double,double,AuxValues::sp,int)>(boost::bind(evaluate,(*this),_1,_2,_3,_4,_5));
  28.  }
  29. private:
  30.  double m_dLambda;
  31. };


 
Et ensuite je reprend la classe de base EQPDEPricerProperty_Base pour définir l'opérateur suivant:
 

Code :
  1. friend sp operator*(double dLambda,sp spP)
  2.  {
  3.   EQScalarMultProperty<-1000,EQPDEProperty_Base,EQPDEProperty_Base>::sp
  4.    spProperty(new EQScalarMultProperty<-1000,EQPDEProperty_Base,EQPDEProperty_Base>(dLambda,spP));
  5.   return spProperty;
  6.  }
  7.  friend sp operator*(sp spP,double dLambda)
  8.  {
  9.   EQScalarMultProperty<-1000,EQPDEProperty_Base,EQPDEProperty_Base>::sp
  10.    spProperty(new EQScalarMultProperty<-1000,EQPDEProperty_Base,EQPDEProperty_Base>(dLambda,spP));
  11.   return spProperty;
  12.  }


 
Bien entendu si j'enlève le friend j'ai une belle erreur de compilation:
 
d:\HLML2\EQUITY\EQ\BSCHModelEQ\PDEPricerProperties.hpp(912) : error C2804: binary 'operator *' has too many parameters
d:\HLML2\EQUITY\EQ\BSCHModelEQ\PDEPricerProperties.hpp(912) : error C2333: 'EQPDEProperty_Base::operator`*'' : error in function declaration; skipping function body
 
Bon alors il y a toujours la solution de me dire que je fais n'importequoi (en fait c'est une possibilité tout à fait crédible), m'enfin l'idée c'est d'avoir des modules qui représente des produits financiers et de les combiner pour faire des produits structurés (sauf qu'en fait c'est un peu comme additioner des choux et des carottes) et qu'à la fin je veux faire de l'algèbre avec des pointeurs style:

Code :
  1. spResult = 2*(spCall+1)-spSwap+spCall2*spCall3;


Donc en fait là ca marche mais je suis loin d'être sûr que ce soit bien fait. En plus comme je suis un gros malade, je fais aussi fonctionner mes classe d'opérateurs directement sur les objets genre je veux faire des trucs du style:

Code :
  1. Result = 2*(Call+1)-Swap+Call2*Call3;

Reply

Marsh Posté le 03-04-2008 à 14:53:57   

Reply

Marsh Posté le 03-04-2008 à 15:15:41    

bon déjà un bon point pr utiliser du boost ^^
Après sans plus de code j'ai du mal à voire mais tes fonctions friends elles sont bien défini comme fonctions libres A L'EXTÉRIEUR de toutes classes ?
 
Sinon si t'as du courage : boost::proto ;)

Reply

Marsh Posté le 03-04-2008 à 15:29:55    

Non elles sont friend à l'intérieur de la classe de base EQPDEPRoperty_Base à la Barton-Nackman. J'ai pas écrit toute la classe parce que c'est long et que bon je publie pas vraiment le code sans autorisation ;)

Message cité 1 fois
Message édité par ElDesdichado le 03-04-2008 à 15:31:15
Reply

Marsh Posté le 03-04-2008 à 15:46:14    

Soit dit en passant j'ai jeté un coup d'œil à proto (connaissait pas) et c'est cool/sympa/très frais, ça revient un peu à faire ce que j'ai fait (enfin ils font mieux). Par contre je vais pas avoir le courage/temps pour réécrire ce que j'ai fait en proto, dommage...

Reply

Marsh Posté le 03-04-2008 à 18:05:48    

ElDesdichado a écrit :

Non elles sont friend à l'intérieur de la classe de base EQPDEPRoperty_Base à la Barton-Nackman. J'ai pas écrit toute la classe parce que c'est long et que bon je publie pas vraiment le code sans autorisation ;)

 

si tes declarations sont dans la classe ... elles sont considérés comem mebre qqd tu enleves firends.
il faut enlever friends ET les sortir du corps de la classe

 
ElDesdichado a écrit :

Soit dit en passant j'ai jeté un coup d'œil à proto (connaissait pas) et c'est cool/sympa/très frais, ça revient un peu à faire ce que j'ai fait (enfin ils font mieux). Par contre je vais pas avoir le courage/temps pour réécrire ce que j'ai fait en proto, dommage...

 

moi même j'ai lâché mon vieux générateur de code en Expr Template fait main pour ça.
Le fait d'avoir une vrai notion de grammaire c'est enormissime


Message édité par Joel F le 03-04-2008 à 18:07:06
Reply

Marsh Posté le 05-04-2008 à 08:36:57    

Joel F a écrit :


Sinon si t'as du courage : boost::eroto ;)


Du spam pour le Viagra ! [:cerveau lent]


---------------
Les aéroports où il fait bon attendre, voila un topic qu'il est bien
Reply

Marsh Posté le 05-04-2008 à 08:45:48    

C'est si mal que ça d'utiliser le mot clé friend ?

Reply

Marsh Posté le 05-04-2008 à 10:18:17    

el muchacho a écrit :


Du spam pour le Viagra ! [:cerveau lent]


 
Proto pas eroto :o pervers !
 
@xilebo : oui ca réduit l'encapsulation et ca montre que le designer n'a pas compris le principe de suircharge d'opérateurs.
Il y a moins d'1 cas sur 1000 ou tu ne peut pas reecrire une fonction firends sans friends et sans perte d'expressivité (modulo des problemes d'interfacages non-intrusifs qui n'arrive que rarement)

Reply

Marsh Posté le 05-04-2008 à 10:53:51    

Un article tres interessant de Scott Meyers : "How Non-Member Functions Improve Encapsulation".
http://www.ddj.com/cpp/184401197

Reply

Marsh Posté le 05-04-2008 à 11:30:26    

Ace17 a écrit :

Un article tres interessant de Scott Meyers : "How Non-Member Functions Improve Encapsulation".
http://www.ddj.com/cpp/184401197

 

Merci pour le lien :D C'ets exactement à celui là que je penser

 
Citation :


Conventional wisdom notwithstanding, use of non-friend non-member functions improves a class's encapsulation

 

Emphasis mine


Message édité par Joel F le 05-04-2008 à 11:32:36
Reply

Marsh Posté le 05-04-2008 à 11:30:26   

Reply

Marsh Posté le 07-04-2008 à 09:59:53    

J'ai corrigé et tout fonctionne impec. Merci bien!

Reply

Marsh Posté le 07-04-2008 à 11:37:30    

Ah et je dois les spécifier inline pour éviter les pbs de linkages avec les .cpp . Si un jour quelqu'un cherche à faire la même chose, qui sait...

Reply

Marsh Posté le 07-04-2008 à 11:42:22    

oui ca vaut mieux

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed