Bezpieczne przeciążenie operatora strumienia > >

Jest mnóstwo informacji dostępnych na temat przeciążania operator<<, aby naśladować metodę toString(), która konwertuje złożony obiekt na łańcuch znaków. Jestem zainteresowany również zaimplementowaniem odwrotności operator>> do deserializacji łańcucha znaków w obiekt.

Sprawdzając źródło STL, doszedłem do wniosku, że:

istream &operator>>(istream &, Object &);

Byłaby prawidłową sygnaturą funkcji do deserializacji obiektu typu Object. Niestety nie wiem jak to właściwie wdrożyć-konkretnie jak radzić sobie z błędami:

  1. Jak wskazać nieprawidłowe dane w strumieniu? Zrobić wyjątek?
  2. w jakim stanie powinien być strumień, jeśli w strumieniu znajdują się zniekształcone dane?
  3. czy flagi powinny zostać zresetowane przed zwróceniem odniesienia do łączenia operatorów?
Author: Michael Koval, 2009-08-15

3 answers

  1. Jak wskazać nieprawidłowe dane w strumieniu? Zrobić wyjątek?

Należy ustawić fail bit. Jeśli użytkownik strumienia chce, aby wyjątek został wyrzucony, może skonfigurować strumień (używając istream::exceptions), a strumień będzie rzucał odpowiednio. Zrobiłbym to tak, wtedy

stream.setstate(ios_base::failbit);
  1. w jakim stanie powinien być strumień, jeśli w strumieniu znajdują się zniekształcone dane?

W przypadku zniekształconych danych, które nie pasują do formatu, który chcesz przeczytać, Zwykle powinien ustawić bit fail. W przypadku błędów specyficznych dla wewnętrznego strumienia używany jest bit bad (np. jeśli do strumienia nie jest podłączony bufor).

  1. Czy flagi powinny zostać zresetowane przed zwróceniem odniesienia do łączenia operatorów?
Nie słyszałem o czymś takim.

Do sprawdzenia, czy strumień jest w dobrym stanie, możesz użyć klasy istream::sentry. Tworzy obiekt z niego, mijając strumień i true (aby powiedzieć mu, aby nie pomijał białych znaków natychmiast). Wartownik oceni do false, jeśli eof, fail lub bad bit jest ustawiony.

istream::sentry s(stream, true);
if(!s) return stream;
// now, go on extracting data...
 18
Author: Johannes Schaub - litb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-25 00:57:16

Kilka dodatkowych uwag:

  • Przy implementacji operatora > > powinieneś rozważyć użycie bufstream a nie inne przeciążenia operatora>>;

  • Wyjątki występujące podczas operacji należy przetłumaczyć na failbit lub badbit (członkowie streambuf mogą rzucać, w zależności od Klasa używana);

  • Ustawienie stanu może rzucić; jeśli ustawisz stan po złapaniu wyjątek, należy propagować oryginalny wyjątek, a nie the one throwed by setstate;

  • Szerokość to pole, na które należy zwrócić uwagę. Jeśli jesteś biorąc to pod uwagę, należy zresetować go do 0. Jeśli pacjent stosuje inne operator > > aby wykonać podstawowe prace, musisz obliczyć szerokość, którą przechodzisz od tego, który otrzymałeś;

  • Rozważ uwzględnienie lokalizacji.

Lange and Kreft ( Standard C++ IOStreams and Locales ) convert this in even więcej szczegółów. Dają szablon kod do obsługi błędów, które trwa około jednej strony.

 2
Author: AProgrammer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-08-15 06:56:56

Co do flag, to nie wiem czy gdzieś jest jakiś standard, ale warto je zresetować.

Boost ma fajne wrappery raii do tego: IO State Savers

 0
Author: Eugene,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-08-15 06:29:05