Article View: de.comp.lang.c++
Article #1832Re: Probleme beim Vererben von fstream
From: Dietmar Kuehl
Date: Thu, 14 Mar 1996 22:16
Date: Thu, 14 Mar 1996 22:16
123 lines
5949 bytes
5949 bytes
Hi,
ich habe mich ja schonmal gehoerig auf den A**** gesetzt, als ich einen
radikal anderen Ansatz bei einem Problem mit 'ostream's vorgeschlagen
habe... Also kann ich das ruhig nochmal machen :-)
Bernhard Ruch (Bernhard.Ruch@studi.epfl.ch) wrote:
: Ich moechte eine neue Klasse ObjectStream definieren, die von der
: Klasse fstream vererbt wird. Zusaetzlich zu den gewoehnlichen
: fstream-Operationen soll das Lesen und Schreiben von Objekten
: moeglich sein.
Hm. Wenn ich ganz ehrlich bin, vermute ich eher (aufgrund des Rests
Deines Artikels), dass Du in Wirklichkeit Problem und Loesung mixt: Du
moechtest Objekte lesen und schreiben. Wie das geloest wird ist erstmal
noch offen. Allerdings ist unwahrscheinlich, dass Du es vernuenftig
loesen kannst, indem Du von irgendeinen Stream ableitest: Die
verschiedenen Klassen, die von 'ostream' bzw. 'istream' abgeleitet sind
(z.B. 'ofstream' und 'ifstream'; 'fstream' gibt es in der Standard C++
Library garnicht) sind eigentlich nur Hilfsklassen, die ein 'ios' (die
gemeinsame Basisklasse von 'ostream' und 'istream') mit einem Objekt
einer von 'streambuf' abgeleiteten Klasse initialisieren! Die
verschiedene 'streambuf's unterscheiden sich darin WIE die Sachen
geschrieben werden und nicht WAS geschrieben wird. Genauso verhaelt es
auch mit klassen wie '[io]fstream': Es wird ein File zum
schreiben/lesen benutzt. Bei '[io]stringstream' wird ein 'string'
benutzt usw.
WIE ein Objekt von einem Stream gelesen bzw. zu einem Stream
geschrieben wird, wird durch "Extractor" und "Insertor" Funktionen
definiert, also z.B. den folgenden beiden Funktionen:
ostream &operator<< (ostream &os, Object const &obj)
{
// write the 'obj' to the 'os', e.g.:
os << obj.data;
return os;
}
istram &operator>> (istream &is, Object &obj)
{
// read the 'obj' from the 'is', e.g.:
is >> obj.data;
return is;
}
Es empfiehlt sich ggf. eine Dokumentation von Streams zu beschaffen.
Die beiden Buecher aus denen ich den Umgang mit Streams gelernt habe
sind "The C++ IOstreams Handbook", S.Teale, Addison-Wesley (ziemlich
unuebersichtlich, eigentlich nicht zu empfehlen) und "The (Draft)
Standard C++ Library", P.J.Plauger, Prentice Hall (ganz nett, setzt
aber gute C++ Kenntnis voraus und ist eher eine Definition als ein
Tutorial). Es gibt ein deutsches Buch von Bernd E... (ich kann mir den
Namen nicht merken :-(, sorry...). Zu diesem Buch kann ich nichts
sagen, da ich es [noch] nicht gelesen habe.
: Ich definiere also eine Klasse Object, eine Klasse ObjectStream,
: die von fstream abgeleitet ist, und einen Operator << in ObjectStream,
: der als Parameter eine Referenz auf ein Object erhaelt.
: Die Klasse Objekt enthaelt eine Methode SaveData, die als Parameter
: einen ObjectStream erhaelt. In dieser Methode versuche ich, eine Zahl
: in den ObjektStream zu schreiben.
Das laesst man zu diesem Zweck besser bleiben... Wenn Du eine neue
"externe Repraesentation" baust (z.B. eine Stream der in ein Fenster
von irgendeinem GUI schreibt), dann leitest Du von 'streambuf' ab und,
damit man einen passenden Stream einfacher bauen kann (und nur dafuer),
von 'ostream' und 'istream' z.B. 'owindowstream' und 'iwindowstream',
die einen entsprechenden Stream mit dem passenden 'streambuf'
konstruiren.
: Dies fuehrt zum folgenden Code:
[Geloescht, da der Code eh nicht weiterhilft...]
: Wenn ich nun versuche, diesen Code zu compilieren, meldet der Compiler,
: dass er keinen Operator << fuer (ObjectStream, int) kenne, obwohl ja
: ObjectStream von fstream abgeleitet ist und diesen Operator kennen
: muesste:
: g++ -c Test.cc
: Test.cc: In method `void Object::SaveData(class ObjectStream &)':
: Test.cc:20: no match for `operator <<(class ObjectStream, int)'
Der Compiler hat recht! Er sieht nur den 'operator << (ObjectStream,
Object &)', alle anderen Funktionen mit dem gleichen Namen (in diesem
Fall 'operator <<') sind versteckt. Wenn Du sie wirklich benutzen
wolltest (was Du aber in diesem Fall garnicht wirklich willst, siehe
oben), dann koenntest Du es forcieren, z.B. mit 'ostream::operator<<
(17)'.
: Wenn ich nun hingegen aus der Klasse ObjectStream den Operator << fuer
: die Klasse Object herausnehme,
: (i.e. die Linie: "ObjectStream &operator << (const Object &pObject);" )
: dann compiliert das Programm ohne Fehler.
Klar, die Funktionen werden ja nicht mehr versteckt!
: Heisst das, dass ich, falls ich den Operator << fuer die Klasse Object
: ueberladen will, ich ihn auch fuer alle anderen Typen (int, char, long,
: float, etc) neu definieren muss?
Wenn Du auf Deiner Loesung bestehst, dann ja. 'using' kann etwas
abhilfe schaffen, wird aber zum einen noch nicht von allen Compilern
unterstuetzt und macht es auch notwendig, dass man alle Funktionen
nennt (glaube ich). Ausserdem wuerde der folgende Code nicht
funktionieren:
f(ObjectStream &os, Object const &o)
{
os << "object: " << o << "\n";
}
weil 'ostream &ostream::operator<< (char const *)' eine 'ostream&' und
keine 'ObjectStream&' zurueckgibt. Die beste und einfachste Loesung ist
also, einfach "Extractor" und "Inserter" Funktionen zu schreiben, die
z.B. einfach eine passende virtuelle Funktion aufrufen.
--
dietmar.kuehl@uni-konstanz.de
http://www.informatik.uni-konstanz.de/~kuehl
I am a realistic optimist - that's why I appear to be slightly pessimistic
Technical Details
Message-ID:
<4ia5sb$cfk@news.BelWue.DE>Path:
arc1-ca.pugleaf.net!news.belwue.de!uzwil!kuehlReferences:
<31486437.41C6@studi.epfl.ch>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!news.belwue.de!uzwil!kuehl From: kuehl@uzwil.informatik.uni-konstanz.de (Dietmar Kuehl) Newsgroups: de.comp.lang.c++ Subject: Re: Probleme beim Vererben von fstream Date: 14 Mar 1996 22:16:43 GMT Organization: Fakultät für Mathematik und Informatik Message-ID: <4ia5sb$cfk@news.BelWue.DE> References: <31486437.41C6@studi.epfl.ch> Reply-To: dietmar.kuehl@uni-konstanz.de NNTP-Posting-Host: uzwil.informatik.uni-konstanz.de X-Newsreader: TIN [version 1.2 PL2]