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

[g++] Acces aux membres protected depuis les classes derivees

5 réponses
Avatar
John Deuf
Bonjour,

J'essaye de compiler les Streambuf Filters de James Kanze (j'en profite
pour lui dire merci) :

class GB_FilteringOutputStreambufBase : public std::streambuf
{
=2E..
public:
virtual int sync();
virtual std::streambuf* setbuf( char* p , int len );
private:
std::streambuf* myDest;
}

int GB_FilteringOutputStreambufBase::sync()
{
int result( EOF );
if ( myDest !=3D NULL )
{
result =3D myDest->sync(); // (1)
}
return result;
}

streambuf* GB_FilteringOutputStreambufBase::setbuf( char* p , int len )
{
return myDest =3D=3D NULL
? static_cast< streambuf* >( NULL )
: myDest->setbuf( p , len ) ; // (2)
}

J'obtiens les erreurs suivantes (g++ 3.4.2) :

(1) In member function `virtual int
GB_FilteringOutputStreambufBase::sync()':
error: `int std::basic_streambuf<_CharT, _Traits>::sync() [with _CharT
=3D char, _Traits =3D std::char_traits<char>]' is protected
(1) error: within this context

(2) In member function `virtual std::streambuf*
GB_FilteringOutputStreambufBase::setbuf(char*, int)':
error: `std::basic_streambuf<_CharT, _Traits>*
std::basic_streambuf<_CharT, _Traits>::setbuf(_CharT*, std::streamsize)
[with _CharT =3D char, _Traits =3D std::char_traits<char>]' is protected
(2) error: within this context

Apparament, il m'interdit d'appeler les fonctions sync() et setbuf()
depuis GB_FilteringOutputStreambufBase sous le motif que ce sont des
membres protected de streambuf ?
Pourtant comme j'h=E9rite de streambuf je devrais y avoir acc=E8s, non ?
C'est le fait que le streambuf soit un pointeur membre qui pose
probl=E8me ?

Merci d'avance.

5 réponses

Avatar
Falk Tannhäuser
John Deuf wrote:
Apparament, il m'interdit d'appeler les fonctions sync() et setbuf()
depuis GB_FilteringOutputStreambufBase sous le motif que ce sont des
membres protected de streambuf ?
Pourtant comme j'hérite de streambuf je devrais y avoir accès, non ?
C'est le fait que le streambuf soit un pointeur membre qui pose
problème ?


Tu peux appeller pubsync() et pubsetbuf().

Falk

Avatar
kanze
John Deuf wrote:

J'essaye de compiler les Streambuf Filters de James Kanze
(j'en profite pour lui dire merci) :


D'après le code que tu postes, tu en as une version assez
ancienne, qui prend pas en compte les nouveaux flux. Mais
j'avoue que je ne comprends pas alors les std::. Je croyais
d'avoir pris en compte les nouveaux flux avant d'avoir ajouter
les std::. D'ailleurs, autant que je m'en souviens, j'utilisais
des macros GB_iostd et GB_std, plutôt que std, jusqu'à très
récemment, quand j'ai laissé tomber le support pour les anciens
flux (qui depuis longtemps ne servait plus que pour g++ 2.95.x).

class GB_FilteringOutputStreambufBase : public std::streambuf


Dans les versions précédantes, il me semble d'avoir dérivé de
GB_iostd::streambuf, et non de std::streambuf. GB_iostd était un
macro, défini dans les fichiers qui dépendent du système, pour
résoudre soit à std (nouveaux flux), soit à rien (anciens flux).

{
...
public:
virtual int sync();
virtual std::streambuf* setbuf( char* p , int len );
private:
std::streambuf* myDest;
}

int GB_FilteringOutputStreambufBase::sync()
{
int result( EOF );
if ( myDest != NULL )
{
result = myDest->sync(); // (1)


result = myDest->pubsync() ;

dans la version actuelle. Et depuis un moment, je crois. Dans
les en-têtes système, pour les anciens flux, pubsync est un
macro :

#define pubsync sync

Ça ne me plaisait pas outremesure, mais c'était toujours vu
comme une solution de transition. Depuis quelques mois,
maintenant, j'ai laissé tomber le support pour les anciens flux,
et le macro n'existe donc plus.

}
return result;
}

streambuf* GB_FilteringOutputStreambufBase::setbuf( char* p , int len )
{
return myDest == NULL
? static_cast< streambuf* >( NULL )
: myDest->setbuf( p , len ) ; // (2)
}


return myDest == NULL
? static_cast< std::streambuf* >( NULL )
: myDest->pubsetbuf( p, len ) ;

dans la dernière version.

J'obtiens les erreurs suivantes (g++ 3.4.2) :

(1) In member function `virtual int
GB_FilteringOutputStreambufBase::sync()':
error: `int std::basic_streambuf<_CharT, _Traits>::sync() [with _CharT
= char, _Traits = std::char_traits<char>]' is protected
(1) error: within this context

(2) In member function `virtual std::streambuf*
GB_FilteringOutputStreambufBase::setbuf(char*, int)':
error: `std::basic_streambuf<_CharT, _Traits>*
std::basic_streambuf<_CharT, _Traits>::setbuf(_CharT*, std::streamsize)
[with _CharT = char, _Traits = std::char_traits<char>]' is protected
(2) error: within this context

Apparament, il m'interdit d'appeler les fonctions sync() et
setbuf() depuis GB_FilteringOutputStreambufBase sous le motif
que ce sont des membres protected de streambuf ?


Tout à fait.

Pourtant comme j'hérite de streambuf je devrais y avoir accès,
non ?


Non. En tant que classe dérivée, tu n'as accès des membres
protégés de la classe de base que dans les objets de ton type,
et d'un type qui en dérive. Donc, depuis
GB_FilteringOutputStreambufBase, tu peux appeler sync et setbuf
sur l'objet même, parce que l'accès est à travers this (même si
c'est implicit), et le type de this est
GB_FilteringOutputStreambufBase*. Tu peux aussi les appeler dans
un autre GB_FilteringOutputStreambufBase, si tu en avais. Mais
tu ne peux pas les appeler dans un streambuf tout court (et
c'est le type statique qui compte ici, comme toujours en cas
d'évaluation des protections d'accès).

C'est le fait que le streambuf soit un pointeur membre qui
pose problème ?


Il n'y a aucun pointeur au membre dans le code ci-dessus. C'est
le fait qu'on accède à un streambuf, et non à un
GB_FilteringOutputStreambufBase, qui pose le problème.

Enfin, quelques détails sur les versions de Gabi lib : à part
les std::, le code ci-dessus ressemble à la première version que
j'ai publiée, sur la site gabi-soft.de. Ce code n'avait était
testé qu'avec g++ 2.95.2 (je travaillais professionnellement
avec Java à l'époque), et ne prenait pas en compte les nouveaux
flux. La version qui était disponible longtemps à gabi-soft.fr,
en revanche, essayait à être compatible avec les deux variants
des flux, au moyen des en-têtes spécifiques pour chacun des
en-têtes standard (include de "gb/streambuf.hh", plutôt que
<streambuf>) et des macros comme GB_iostd et pubsync. Cette
version a cessé d'être disponible lors de mon demenagement à
St-Cyr (quand j'ai changé de fournisseur Internet) ; je suis en
train d'essayer à organiser un nouveau site, avec une nouvelle
version -- entre autres, cette version ne supportera plus les
anciens flux.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Avatar
John Deuf
Salut,

Oui, c'est la version qui était sur gabi-soft.de.
J'ai lu ton article dans C++Report, le lien pour les sources portait
vers ce site. Comme il n'est plus disponible, j'ai été cherché les
sources sur archive.org.

J'ai essayé de l'adapter pour les stream disponibles avec mon
compilateur. (Je n'ai pas mis en cause la justesse de ton code, je me
doute bien qu'il fonctionnait, tout au moins à l'époque où tu l'as
écris.)

Pourquoi y a-t-il dorénavant deux versions de sync() et setbuf() dans
les streams standard ?


C'est le fait que le streambuf soit un pointeur membre qui
pose problème ?


Il n'y a aucun pointeur au membre dans le code ci-dessus.


Tu veux dire la façon dont j'appelle "private: std::streambuf*
myDest;" est incorrecte ? Comment peut-on appeller ça ?


Avatar
kanze
John Deuf wrote:

Oui, c'est la version qui était sur gabi-soft.de. J'ai lu ton
article dans C++Report, le lien pour les sources portait vers
ce site.


Vue que j'habitais en Allemagne quand j'ai écris ces
articles...

Comme il n'est plus disponible, j'ai été cherché les
sources sur archive.org.

J'ai essayé de l'adapter pour les stream disponibles avec mon
compilateur. (Je n'ai pas mis en cause la justesse de ton
code, je me doute bien qu'il fonctionnait, tout au moins à
l'époque où tu l'as écris.)

Pourquoi y a-t-il dorénavant deux versions de sync() et
setbuf() dans les streams standard ?


Pour créer des problèmes gratuits de compatibilité.

Sérieusement, il y a de bons arguments contre des fonctions
virtuelles publiques, au moins dans certains cas (dont
celui-ci). Si je faisais la conception de zéro de streambuf, je
crois que je ferais pareil, aux noms près. Mais AMHA, les
avantages sont plutôt de l'ordre théorique, et ne sont
certainement pas suffisants pour justifier la modification d'une
interface établie.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Avatar
James Kanze
John Deuf wrote:


C'est le fait que le streambuf soit un pointeur membre qui
pose problème ?




Il n'y a aucun pointeur au membre dans le code ci-dessus.



Tu veux dire la façon dont j'appelle "private: std::streambuf*
myDest;" est incorrecte ? Comment peut-on appeller ça ?


Une variable membre. De type pointeur, d'accord, mais ce n'est
pas un pointeur au membre.

--
James Kanze mailto:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 pl. Pierre Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34