Comment faire pour hériter de std::ostream?
J'ai cherché sur google et je juste ne pouvez pas trouver une réponse simple à cette question. Et il doit être simple, comme la STL est généralement.
Je veux définir MyOStream qui hérite publiquement de std::ostream. Disons que je veux appeler foo() à chaque fois que quelque chose est écrit dans mon flux.
class MyOStream : public ostream {
public:
...
private:
void foo() { ... }
}
Je comprends que l'interface publique de ostream est non-virtuel, alors comment peut-il être fait?
Je veux que les clients puissent utiliser à la fois l'opérateur<< et write() et put() sur MyOStream et utiliser la capacité étendue de ma classe.
- Le TSL peut-être simple, mais c'est seulement une partie de la norme C++ de la bibliothèque. Le iostreams de la bibliothèque n'ont rien à faire avec (ce qui était une fois) de la STL. STL est fondamentalement contianers + itérateurs + algorithmes. Iostreams, les paramètres régionaux et de tout ce qui a une toute autre origine, et est généralement une douleur à travailler avec 😉
Vous devez vous connecter pour publier un commentaire.
Ce n'est pas une simple question, malheureusement. Les classes que vous devez dériver de sont la
basic_
classes, commebasic_ostream
. Cependant, la dérivation d'un cours d'eau peut ne pas être ce que vous voulez, vous pouvez dériver à partir d'un flux de tampon à la place, puis utiliser cette classe à instancier un flux existant classe.L'ensemble de la région est complexe, mais il y a un excellent livre sur le sujet Standard C++ IOStreams et Locales, qui je vous suggère de jeter un oeil à avant d'aller plus loin.
Je filais ma tête autour de la façon de faire la même chose et j'ai trouvé qu'il n'est pas difficile.
Fondamentalement, il suffit de la sous-classe ostream et le streambuf objets, et la construction de la ostream avec lui-même comme une zone tampon. le virtuel débordement() à partir de std::streambuf sera appelée pour chaque caractère envoyé dans le flux. Pour s'adapter à votre exemple, j'ai juste fait un foo() et la fonction appelée.
oh et ignorer le fait que la fonction principale n'est pas une vraie fonction principale. C'est dans un espace de noms appelé d'ailleurs ;p
Un autre travail pirater pour obtenir un effet similaire est à l'utilisation modèle et la composition
hex
ouendl
T
obtiendrezstd::hex
's type.std::hex
mais pas pourstd::endl
oustd::flush
(et probablement d'autres). C'est parce qu'il ne peut pas résoudre de T pour la fonction type. Ajoutant ce qui suit àLoggedStream
résout le problème:LoggedStream const& operator<<(std::ostream& (*F)(std::ostream&)) const { F(out); return *this; }
std::endl
?Je ne sais pas si c'est la bonne solution, mais j'ai hérité de std::ostream de cette façon. Il utilise une mémoire tampon hérité de std::basic_streambuf et obtient 64 caractères (ou moins si rincé) et les envoie à un générique putChars() la méthode la manipulation des données est effectuée. Il montre également comment donner à l'utilisateur des données.
Live Exemple
Composition, pas d'héritage. Votre classe contient, "encapsule" un ostream&, et les transmet à celle-ci (après l'appel de foo()).