Ich spiele ein wenig mit Streams herum und kann mich nicht mit dem Kopf herumschlagen.Wie erkennt man, ob ein ptr immer noch eine gültige Referenz referenziert, nachdem diese Referenz den Gültigkeitsbereich verlässt
Hier haben wir eine grundlegende ostream ptr, die auf verschiedene Ausgabeströme gesetzt ist, ob es cout
, cerr
oder file
ist.
// ostream ptr
std::ostream* outstream;
// set output ostream
void setOutput(std::ostream & os)
{
outstream = &os;
}
// write message to ostream
void writeData(const std::string & msg)
{
*outstream << msg << '\n';
}
int main (int argc, char * const argv[])
{
// init to std out
setOutput(std::cout);
writeData("message to cout");
setOutput(std::cerr);
writeData("message to cerr");
std::ofstream fileout("test.txt", std::ofstream::out | std::ofstream::app);
setOutput(fileout);
writeData("message to file");
//fileout.close();
setOutput(std::cout);
writeData("message2 to cout");
return 0;
}
Das obige funktioniert perfekt und zeigt die Stärke der C++ Iostream-Implementierung. Perfekt.
Da jedoch der setOutput
durch Verweis festgelegt wird, muss das referenzierte Objekt im Gültigkeitsbereich bleiben. Hier zeigt sich das Problem. Ich möchte einen Weg finden, die Ausgabe auf std::cout
zu setzen, wenn der Ofstream oder irgendein anderer Ostream für ungültig erklärt wird. Das heißt, das Objekt, auf das verwiesen wird, ist oder ist außerhalb des Gültigkeitsbereichs.
Zum Beispiel:
// write message to ostream
void writeData(const std::string & msg)
{
if (/*stream or memory is invalid*/)
setOutput(std::cout);
*outstream << msg << '\n';
}
// local fileout goes out of scope
void foo()
{
std::ofstream fileout("test.txt", std::ofstream::out | std::ofstream::app);
setOutput(fileout);
writeData("message to file");
}
int main (int argc, char * const argv[])
{
setOutput(std::cout);
writeData("message to cout");
foo();
/* problem the local fileout is no longer referenced by the ostream ptr*/
/* the following should be redirected to std::cout cuz of default*/
writeData("message2 to cout");
return 0;
}
Die oben ist gut, bis die foo()
kehrt zur Hauptfunktion. Da geht es schief, weil das lokal definierte ofstream
nicht mehr erreichbar ist.
Offensichtlich ist dies nicht ratsam und der Benutzer sollte dies realisieren. Allerdings möchte ich all dies in eine Protokollierungsklasse einbinden und so den Status des Objekts auch dann gültig halten, wenn der Verdacht auf einen solchen Missbrauch besteht. Dies führt zu einer ungültigen Zugriffsverletzung, die schwer zu finden ist.
Konkrete Frage. Gibt es eine Möglichkeit herauszufinden, ob ein ostream-ptr oder irgendein ptr-Objekt immer noch auf ein gültiges Objekt oder einen Speicherort verweist?
ps: Ich konnte Heap-Speicher verwenden und etwas mit Smart-Pointer tun, aber ehrlich gesagt würde ich es so halten will, wenn möglich
"Konkrete Frage. Gibt es eine Möglichkeit, herauszufinden, ob ein ostream ptr oder irgendein ptr für diese Angelegenheit immer noch auf ein gültiges Objekt oder einen Speicherort verweist?" - Ja: Java. – nicomp
@nicomp mag nicht java – Montaldo
@Captain Obvlious aber es ist alles auf dem Stapel. Ich habe das versucht, aber Sie können immer noch nicht erkennen, ob es außerhalb des Geltungsbereiches afaik – Montaldo