Nous avons vu dans la Section 8.12 un exemple d'application des classes de flux d'entrée / sortie de la bibliothèque pour les entrées / sorties standards des programmes. En réalité, ces classes de gestion des flux s'intègrent dans une hiérarchie complexe de classes permettant de manipuler les flux d'entrée / sortie et pas seulement pour les entrées / sorties standards.
En effet, afin de faciliter la manipulation des flux d'entrée / sortie, la bibliothèque standard C++ fournit tout un ensemble de classes template. Ces classes sont paramétrées par le type de base des caractères qu'elles manipulent. Bien entendu, les types de caractères les plus utilisés sont les type char et wchar_t, mais il est possible d'utiliser a priori n'importe quel autre type de donnée pour lequel une classe de traits char_traits est définie.
Ce chapitre a pour but de détailler cette hiérarchie de classes. Les principes de base et l'architecture générale des flux C++ seront donc abordés dans un premier temps, puis les classes de gestion des tampons seront traitées. Les classes génériques de gestion des flux d'entrée / sortie seront ensuite décrites, et ce sera enfin le tour des classes de gestion des flux orientés chaînes de caractères et des classes de gestion des flux orientés fichiers.
Les classes de la bibliothèque d'entrée / sortie de la bibliothèque standard se subdivisent en deux catégories distinctes.
La première catégorie regroupe les classes de gestion des tampons d'entrée / sortie. Ces classes sont au nombre de trois : la classe template basic_stringbuf, qui permet de réaliser des tampons pour les flux orientés chaînes de caractères, la classe template basic_filebuf, qui prend en charge les tampons pour les flux orientés fichiers, et leur classe de base commune, la classe template basic_streambuf. Le rôle de ces classes est principalement d'optimiser les entrées / sorties en intercalant des tampons d'entrée / sortie au sein même du programme. Ce sont principalement des classes utilitaires, qui sont utilisées en interne par les autres classes de la bibliothèque d'entrée / sortie.
La deuxième catégorie de classes est de loin la plus complexe, puisqu'il s'agit des classes de gestion des flux eux-mêmes. Toutes ces classes dérivent de la classe template basic_ios (elle-même dérivée de la classe de base ios_base, qui définit tous les types et les constantes utilisés par les classes de flux). La classe basic_ios fournit les fonctionnalités de base des classes de flux et, en particulier, elle gère le lien avec les tampons d'entrée / sortie utilisés par le flux. De cette classe de base dérivent des classes spécialisées respectivement pour les entrées ou pour les sorties. Ainsi, la classe template basic_istream prend en charge toutes les opérations des flux d'entrée et la classe basic_ostream toutes les opérations des flux de sortie. Enfin, la bibliothèque standard définit la classe template basic_iostream, qui regroupe toutes les fonctionnalités des classes basic_istream et basic_ostream et dont dérivent toutes les classes de gestion des flux mixtes.
Les classes basic_istream, basic_ostream et basic_iostream fournissent les fonctionnalités de base des flux d'entrée / sortie. Ce sont donc les classes utilisées pour implémenter les flux d'entrée / sortie standards du C++ cin, cout, cerr et clog, que l'on a brièvement présentés dans la Section 8.12. Cependant, ces classes ne prennent pas en charge toutes les spécificités des médias avec lesquels des flux plus complexes peuvent communiquer. Par conséquent, des classes dérivées, plus spécialisées, sont fournies par la bibliothèque standard. Ces classes prennent en charge les entrées / sorties sur fichier et les flux orientés chaînes de caractères.
La bibliothèque standard fournit donc deux jeux de classes spécialisées pour les entrées / sorties dans des fichiers et dans des chaînes de caractères. Pour chacune des classes de base basic_istream, basic_ostream et basic_iostream il existe deux classes dérivées, une pour les fichiers, et une pour les chaînes de caractères. Par exemple, les classes template basic_ifstream et basic_istringstream dérivent de la classe basic_istream et prennent en charge respectivement les flux d'entrée à partir de fichiers et les flux d'entrée à partir de chaînes de caractères. De même, la bibliothèque standard définit les classes template basic_ofstream et basic_ostringstream, dérivées de la classe basic_ostream, pour les flux de sortie dans des fichiers ou dans des chaînes de caractères, et les classes template basic_fstream et basic_stringstream, dérivées de la classe basic_iostream, pour les flux d'entrée / sortie sur les fichiers et les chaînes de caractères.
Note : Cette hiérarchie de classes est assez complexe et peut paraître étrange au niveau des classes des flux mixtes. En effet, la classe basic_fstream ne dérive pas des classes basic_ifstream et basic_ofstream mais de la classe basic_iostream, et c'est cette classe qui dérive des classes basic_istream et basic_ostream. De même, la classe basic_stringstream ne dérive pas des classes basic_istringstream et basic_ostringstream, mais de la classe basic_iostream.
Comme il l'a déjà été dit, toutes ces classes template peuvent être instanciées pour n'importe quel type de caractère, pourvu qu'une classe de traits char_traits soit définie. Cependant, en pratique, il n'est courant d'instancier ces classes que pour les types de caractères de base du langage, à savoir les types char et wchar_t.
Historiquement, les classes d'entrée / sortie des bibliothèques fournies avec la plupart des implémentations n'étaient pas template et ne permettaient de manipuler que des flux basés sur le type de caractère char. Les implémentations disposant de classes de flux d'entrée / sortie capables de manipuler les caractères de type wchar_t étaient donc relativement rares. À présent, toutes ces classes sont définies comme des instances des classes template citées ci-dessus. Par souci de compatibilité, la bibliothèque standard C++ définit tout un jeu de types pour ces instances qui permettent aux programmes utilisant les anciennes classes de fonctionner. Ces types sont déclarés de la manière suivante dans l'en-tête iosfwd (mais sont définis dans leurs en-têtes respectifs, que l'on décrira plus tard) :
// Types de base des tampons : typedef basic_streambuf<char> streambuf; typedef basic_streambuf<wchar_t> wstreambuf; typedef basic_stringbuf<char> stringbuf; typedef basic_stringbuf<wchar_t> wstringbuf; typedef basic_filebuf<char> filebuf; typedef basic_filebuf<wchar_t> wfilebuf; // Types de base des flux d'entrée / sortie : typedef basic_ios<char> ios; typedef basic_ios<wchar_t> wios; // Types des flux d'entrée / sortie standards : typedef basic_istream<char> istream; typedef basic_istream<wchar_t> wistream; typedef basic_ostream<char> ostream; typedef basic_ostream<wchar_t> wostream; typedef basic_iostream<char> iostream; typedef basic_iostream<wchar_t> wiostream; // Types des flux orientés fichiers : typedef basic_ifstream<char> ifstream; typedef basic_ifstream<wchar_t> wifstream; typedef basic_ofstream<char> ofstream; typedef basic_ofstream<wchar_t> wofstream; typedef basic_fstream<char> fstream; typedef basic_fstream<wchar_t> wfstream; // Types des flux orientés chaînes de caractères : typedef basic_istringstream<char> istringstream; typedef basic_istringstream<wchar_t> wistringstream; typedef basic_ostringstream<char> ostringstream; typedef basic_ostringstream<wchar_t> wostringstream; typedef basic_stringstream<char> stringstream; typedef basic_stringstream<wchar_t> wstringstream;
Les objets cin, cout, cerr et clog sont donc des instances des classes istream et ostream, qui sont associées aux flux d'entrée / sortie standards du programme. En fait, la bibliothèque standard définit également des versions capables de manipuler des flux basés sur le type wchar_t pour les programmes qui désirent travailler avec des caractères larges. Ces objets sont respectivement wcin (instance de wistream), wcout, wcerr et wclog (instances de wostream). Tous ces objets sont initialisés par la bibliothèque standard automatiquement lorsqu'ils sont utilisés pour la première fois, et sont donc toujours utilisables.
Note : En réalité, sur la plupart des systèmes, les flux d'entrée / sortie standards sont les premiers descripteurs de fichiers que le système attribue automatiquement aux programmes lorsqu'ils sont lancés. En toute logique, les objets cin, cout, cerr et clog devraient donc être des instances de classes de gestion de flux orientés fichiers. Cependant, ces fichiers ne sont pas nommés d'une part et, d'autre part, tous les systèmes ne gèrent pas les flux d'entrée / sortie standards de la même manière. Ces objets ne sont donc pas toujours des flux sur des fichiers et la bibliothèque standard C++ ne les définit par conséquent pas comme tels.
Précédent | Sommaire | Suivant |
Les types numériques | Niveau supérieur | Les tampons |