Основные функции классов ios, istream, ostream
Из диаграммы классов ввода−вывода следует, что классы ios, istream, ostream являются базовыми для большинства классов. Класс ios является типом-синонимом для шаблона класса basic_ios, производным от класса ios_base.
template <class E, class T = char_traits<E> >
class basic_ios : public ios_base
{public:
iostate rdstate() const; // возвращает текущее состояние потока
void clear(iostate state = goodbit); // устанавливает состояние потока в
// заданное значение. Состояние потока
// можно изменить: cin.clear(ios::eofbit)
void setstate(iostate state);
bool good() const; // true-значение при отсутствии ошибки
bool eof() const; // true при достижении конца файла, т.е. при попыт-
// ке выполнить ввод−вывод за пределами файла
bool fail() const; // true при ошибке в текущей операции
bool bad() const; // true при ошибке
basic_ostream<E, T> *tie() const;
basic_ostream<E, T> *tie(basic_ostream<E, T> *str);
basic_streambuf<E, T> *rdbuf() const; // возвращает указатель на буфер
// ввода−вывода
basic_streambuf<E, T> *rdbuf(basic_streambuf<E, T> *sb);
basic_ios& copyfmt(const basic_ios& rhs);
locale imbue(const locale& loc);
E widen(char ch);
char narrow(E ch, char dflt);
protected:
basic_ios();
void init(basic_streambuf<E, T>* sb);
};
Далее приводятся прототипы некоторых функций классов istream и ostream.
template <class E, class T = char_traits<E> >
class basic_istream : virtual public basic_ios<E, T>
{public:
bool ipfx(bool noskip = false);
void isfx();
streamsize gcount() const;
int_type get();
basic_istream& get(E& c);
basic_istream& get(E *s, streamsize n);
basic_istream& get(E *s, streamsize n, E delim);
basic_istream& get(basic_streambuf<E, T> *sb);
basic_istream& get(basic_streambuf<E, T> *sb, E delim);
basic_istream& getline(E *s, streamsize n)E
basic_istream& getline(E *s, streamsize n, E delim);
basic_istream& ignore(streamsize n = 1, // пропускает n символов или
int_type delim = T::eof()); // завершается при считывании
// заданного ограничителя по
// умолчанию − EOF
int_type peek(); // читает символ из потока, не удаляя его из потока
basic_istream& read(E *s, streamsize n); // неформатированный ввод
streamsize readsome(E *s, streamsize n);
basic_istream& putback(E c);// возвращает обратно в поток предыдущий
// символ, полученный из потока функцией get
basic_istream& unget();
pos_type tellg();
basic_istream& seekg(pos_type pos);
basic_istream& seekg(off_type off, ios_base::seek_dir way);
int sync();
};
template <class E, class T = char_traits<E> >
class basic_ostream : virtual public basic_ios<E, T>
{public:
bool opfx();
void osfx();
basic_ostream& put(E c);
basic_ostream& write(E *s, streamsize n); // неформатированный вывод
basic_ostream& flush();
pos_type tellp();
basic_ostream& seekp(pos_type pos);
basic_ostream& seekp(off_type off, ios_base::seek_dir way);
};
8. ИСКЛЮЧЕНИЯ В С++
Исключения – возникновение непредвиденных условий, например, деление на ноль, невозможность выделения памяти при создании нового объекта и т.д. Обычно эти условия завершают выполнение программы с системной ошибкой. С++ позволяет восстанавливать программу из этих условий и продолжать ее выполнение. В то же время исключение – это более общее, чем ошибка, понятие и может возникать и тогда, когда в программе нет ошибок.
Механизм обработки исключительных ситуаций является неотъемлемой частью языка С++. Этот механизм предоставляет программисту средство реагирования на нештатные события и позволяет преодолеть ряд принципиальных недостатков следующих традиционных методов обработки ошибок:
- возврат функцией кода ошибки;
- возврат значений ошибки через аргументы функций;
- использование глобальных переменных ошибки;
- использование оператора безусловного перехода goto или функций setjmp/longjmp;
- использование макроса assert.
Возврат функцией кода ошибки является самым обычным и широко применяемым методом. Однако этот метод имеет существенные недостатки. Во-первых, нужно помнить численные значения кодов ошибок. Эту проблему можно обойти, используя перечисляемые типы. Но в некоторых случаях функция может возвращать широкий диапазон допустимых (неошибочных) значений, и тогда сложно найти диапазон для возвращаемых кодов ошибки. Это и является вторым недостатком. И, в-третьих, при использовании такого механизма сигнализации об ошибках вся ответственность по их обработке ложится на программиста и могут возникнуть ситуации, когда серьезные ошибки могут остаться без внимания.
Возврат кода ошибки через аргумент функции или использование глобальной переменной ошибки снимают прежде всего вторую проблему, однако по-прежнему остаются первая и третья. Кроме того, использование глобальных переменных не является особо позитивным фактором.
Использование оператора безусловного перехода в любых ситуациях является нежелательным, кроме того, оператор goto действует только в пределах функции. Пара функций setjmp/longjmp является довольно мощным средством, однако и этот метод имеет серьезнейший недостаток: он не обеспечивает вызов деструкторов локальных объектов при выходе из области видимости, что, естественно, влечет за собой утечку памяти.
И, наконец, макрос assert является скорее средством отладки, чем средством обработки нештатных событий, возникающих в процессе использования программы.
Таким образом, необходим некий другой способ обработки ошибок, который учитывал бы объектно-ориентированную философию. Таким способом и является механизм обработки исключительных ситуаций.