cs_foxz
Messages postés101Date d'inscriptionmercredi 8 octobre 2003StatutMembreDernière intervention25 février 2009
-
7 août 2007 à 10:01
cs_foxz
Messages postés101Date d'inscriptionmercredi 8 octobre 2003StatutMembreDernière intervention25 février 2009
-
7 août 2007 à 18:19
Bonjour,
d'une maniere general.
class strm{ // base stream
virtual int w(void*,int)=0; // write
virtual int r(void*,int)=0; //read
};
class fil:virtual public strm{ // file stram
virtual int w(void*b,int z){...}; // write
virtual int r(void*b,int z){...}; //read
};
class mem:virtual public strm{ // memory stream
virtual int w(void*b,int z){...}; // write
virtual int r(void*b,int z){...}; //read
};
pour le moment pas de probleme.
maintenant je voudrais rajouter un compresseur (Zip) de maniere dynamique et transparent
La seul solution que je vois c le multi heritage
#define vp virtual public
class zip:vp strm{
virtual int w(void*,int){...}; // write ... je detourne la fonction de base pour compressé le flux
virtual int r(void*,int){...}; //read
};
maintenant, si je veux utilisé un flux fichier compressé.
class fz:vp fil, vp zip{};
...
{
fz x;
x.w(&buffer,100);
};
la le compilateur plante (et c normal).
avez vous une idee de comment contourné le probleme
d'une maniere elegante.
moi, je me suis perdu du cote des pointers de fonction
int (*w)(void*,int);
mais la le compilo gueule parce que
int(*w) c pas la meme chose que int(class:*)
(un pointer sur une fonction d'une class... normal que les fonctions de class push this)
j'ai essaye
int (strm::*w)(...);
la ca marche...
sauf que le compilo plante sur
x.w(...); // y dit qu'il manque .* ou ->* j'ai essaye les 2 et ca plante.
pour le moment je passe par des fonctions static :
static int wr(strm*x,void*b,int z){}
le probleme des fonctions static c que this n'est pas pushé (d'ou le strm*x... bonjour le transtypage dynamic_cast !!!)
puis on ne peux pas les virtualisés (si, si, j'y tiens)
Je cherche ABSOLUMENT à utilisé le multi-heritage.
car
1/ j'ai d'autre type de flux (TCP...)
2/ d'autre type de manipulateur (Zip, crypt, buffer, content...) mixable : class fzc:vp zip, vp crypt ce qui donne un flux compressé et encrypter.
3/ je vaudrais generalisé le principe a autre chose que du flux.
cs_juju12
Messages postés966Date d'inscriptionsamedi 3 avril 2004StatutMembreDernière intervention 4 mars 20104 7 août 2007 à 10:40
Y a un truc que je comprends pas : pourquoi fz hérite-t'il de strm puisque zip l'interface déjà de manière publique (pas de méthodes masquées donc)? D'ailleurs mon compilo (VC2005 express) me met un warning
D'autre part pour la fonction w (ou r) de fz, est-ce que tu en fais une nouvelle implémentation pour fz ou tu utilises une de zip ou strm? dans ce cas il faut préciser laquelle pour lever l'ambigüité :
fz x;
x.zip::w(...) ou x.strm::w(..);
au pire tu peux faire ça je pense:
inline virtual int fz::w(...) {return this->zip::w(...);}
cs_foxz
Messages postés101Date d'inscriptionmercredi 8 octobre 2003StatutMembreDernière intervention25 février 2009 7 août 2007 à 12:05
le but est que quand tu fais x.w(...)
zip.w soit appelé.
puis zip.w appel fil.w
(je compresse le flux puis je l'ecris sur le disque)
this->zip::w ok... mais comment faire quand le flux fil est compressé puis encrypter ???
class fzc:vp fil,vp zip, vp crypt {};
(crypt etant de la meme implementation que zip)
imagine : j'ai 3 type de flux (fil,tcp,mem) mais je peux avoir un tas de "modificateur".
zip, enc, buf, cat etc... de plus je peux imbriqué les "modificateurs"
zip, enc par exemple.
je ne trouve pas ca elegeant de coder toutes les possibilités.
j'essaye de voir du coté des templates...
cs_juju12
Messages postés966Date d'inscriptionsamedi 3 avril 2004StatutMembreDernière intervention 4 mars 20104 7 août 2007 à 13:21
OK désolé j'avais mal lu (zip hérite expicitemen de fil et pas de strm). Ce que tu voudrais en fait, c'est appeler toutes les méthodes w() des classes héritées. C'est vrai que coder en dur est une solution:
inline int fzc::w(...)
{
this->zip::w(...);
this->crypt::w(...);
return this->fil::w(...);
}
Maintenant si effectivement tu as plein de possibilités...
cs_foxz
Messages postés101Date d'inscriptionmercredi 8 octobre 2003StatutMembreDernière intervention25 février 2009 7 août 2007 à 14:19
Bah si tu veux en passant par des pointer de fonction de membre static ca fonction bien
mais je trouve chiant de passé "this" en parametre pour le transtypé apres.
bon j'ai trouvé pour mon histoire de int(strm::*)(int).
il faut faire (this->*w)(...)
ca devrait m'eviter de pushé this...
mais j'ai tres peur du resultat.
(apparament int(strm::*)(...) donne un deplacement par rapport au this de strm...)
FoxZ...
Vous n’avez pas trouvé la réponse que vous recherchez ?
cs_foxz
Messages postés101Date d'inscriptionmercredi 8 octobre 2003StatutMembreDernière intervention25 février 2009 7 août 2007 à 14:47
struct SCstrmwr{ // la function avec this
SomeClass *sclass;
int (SomeClass::*sfunc)(void*,int);
};
class strm2{
public:
SCstrmwr _w; // _w sera surchargé par chaque "modificateur"
virtual int w(void*b,int z){
return (_w.sclass->*_w.sfunc)(b,z); // voici la ligne magique
};
};
class fil2:vp strm2{
virtual int fw (void*b,int z){};
public:
fil2(){
std::cout << "fil2.w\n";
_w.sclass=(SomeClass*)this;
_w.sfunc=(int (SomeClass::*)(void*,int))&fil2::w;
};
};
voila qui me parait ++ elegant non ?
bon... une piste pour mettre ca dans des templates ??
cs_juju12
Messages postés966Date d'inscriptionsamedi 3 avril 2004StatutMembreDernière intervention 4 mars 20104 7 août 2007 à 16:05
Cela dit ca me parait bizarre : tu stockes l'adresse de strm2::w dans le pointeur de fonction sfunc et après quand tu appelles strm2::w, le code rappelle w etc... ca boucle à l'infini.
J'ai peut-être mal compris (bien sûr). Mais y a autre chose : comment veux-tu appliquer le principe à plusieurs classes héritées?