Программирование. Принципы и практика использования C++ Исправленное издание, стр. 266
vectornewdelete19.5.3. Гарантии
Что делать, если вектор невозможно ограничить только одной областью (или подобластью) видимости? Рассмотрим пример.
vector<int>* make_vec() // создает заполненный вектор{ vector<int>* p = new vector<int>; // выделяем свободную память // ...заполняем вектор данными; // возможна генерация исключения... return p;}Это довольно распространенный пример: мы вызываем функцию, чтобы создать сложную структуру данных, и возвращаем эту структуру как результат. Однако, если при заполнении вектора возникнет исключение, функция
make_vec()vectormake_vec()Для того чтобы сгенерировать исключение, мы можем добавить блок
tryvector<int>* make_vec() // создает заполненный вектор{ vector<int>* p = new vector<int>; // выделяет свободную память try { // ...заполняем вектор данными; // возможна генерация исключения... return p; } catch (...) { delete p; // локальная очистка throw; // повторно генерируем исключение, // чтобы вызывающая // функция отреагировала на то, что функция // make_vec() не сделала то, что требовалось }}
make_vec()vector(vector::at()make_vec()throwЭто простой и эффективный способ обработки ошибок, который можно применять систематически.
• Базовая гарантия. Цель кода
try ... catchmake_vec()• Жесткая гарантия. Если кроме базовой гарантии, функция также гарантирует, что все наблюдаемые значения (т.е. все значения, не являющиеся локальными по отношению к этой функции) после отказа восстанавливают свои предыдущие значения, то говорят, что такая функция дает жесткую гарантию (strong guarantee). Жесткая гарантия — это идеал для функции: либо функция будет выполнена так, как ожидалось, либо ничего не произойдет, кроме генерирования исключения, означающего отказ.
• Гарантия отсутствия исключений (no-throw guarantee). Если бы мы не могли выполнять простые операции без какого бы то ни было риска сбоя и без генерирования исключений, то не могли бы написать код, соответствующий условиям базовой и жесткой гарантии. К счастью, практически все встроенные средства языка С++ поддерживают гарантию отсутствия исключений: они просто не могут их генерировать. Для того чтобы избежать генерирования исключений, просто не выполняйте оператор
thrownewДля анализа правильности программы наиболее полезными являются базовая и жесткая гарантии. Принцип RAII играет существенную роль для реализации простого и эффективного кода, написанного в соответствии с этими идеями. Более подробную информацию можно найти в приложении Д книги Язык программирования С++.
19.5.4. Класс auto_ptr
Итак, функции, такие как
make_vec()try ... catchvector<int><memory>auto_ptrvector<int>* make_vec() // создает заполненный вектор{ auto_ptr< vector<int> > p(new vector<int>); // выделяет свободную // память // ...заполняем вектор данными;