|
|
The G2++ programming language interface achieves much of its flexibility, while retaining complete type safety, by using the iostream(C++) architecture. For example, consider untyped I/O:
C interface (g2.h) int getbuf(G2BUF*,FILE*); int putbuf(G2BUF*,FILE*); C++ interface (g2++.h) istream& operator>>(istream&,G2BUF&); ostream& operator<<(ostream&,const G2BUF&);
Flexibility is achieved in the following way. There are certain contexts in which C++ permits substitution of one type for another; one such context is that in which an object of a derived class is passed to a function having a reference parameter of the base class type:
class my_ostream : public ostream{ ... }; my_ostream os; G2BUF x; os << x;
Several useful classes have already been derived from istream and ostream; each of these specializes its base class for a particular kind of character source or sink and buffering paradigm:
#include <strstream.h> #include "usr.h" const int BUFSIZE = 100; char buf[BUFSIZE]; main(){ USR u; ostrstream os(buf,BUFSIZE); ... os << u; }
#include <Strstream.h> #include "usr.h" String buf; main(){ USR u; Ostrstream os(buf); ... os << u; }
#include <fstream.h> #include "usr.h" main(){ USR u; ofstream os("X"); ... os << u; }
#include <ipcstream.h> #include "usr.h" main(){ USR u; ipc_attachment att("X"); att.listen(); ipcstream os(att); ... os << u; }
Note how insertion looks the same in all five examples, regardless of the type of the ostream. Similar examples could be written to illustrate this uniformity for stream extraction and untyped I/O.