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:
- Jak wskazać nieprawidłowe dane w strumieniu? Zrobić wyjątek?
- w jakim stanie powinien być strumień, jeśli w strumieniu znajdują się zniekształcone dane?
- czy flagi powinny zostać zresetowane przed zwróceniem odniesienia do łączenia operatorów?
3 answers
- 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);
- 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).
- Czy flagi powinny zostać zresetowane przed zwróceniem odniesienia do łączenia operatorów?
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...
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.
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
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