Время существования объектов и управление ресурсами (самомоднейшее C++)
В отличие от управляемых языков C++ не поддерживает сбор мусора (GC), который автоматически освобождает ресурсы памяти нет больше используется во время выполнения программы.В C++ управление ресурсами непосредственно связано с временем жизни объекта.Этот документ описывает факторы, которые влияют на время жизни объектов в C++ и как управлять им.
C++ не GC, главным образом потому, что он не обрабатывает ресурсы оперативной памяти.Только детерминированные деструкторы как в C++ может обрабатывать столь же ресурсы памяти и оперативной памяти.Сборщик Мусора имеет также другие проблемы, как нагрузка в памяти и ЦП и размещение.Но universality — это фундаментальная проблема, не устранен через правильное оптимизации.
Основные понятия
Важная вещь в управление временем жизни объекта является инкапсуляция, кто использует объект не должен знать, что владеет ресурсами, которые объект, или как избавиться от них или даже ли она является владельцем всех ресурсов на всех.Он имеет только для уничтожения объекта.Базовый язык C++ разработан чтобы убедиться, что объекты уничтожаются в правильное время, то есть как блоки завершился в обратном порядке конструкции.При удалении объекта его базовых классов и членов, уничтожаются в определенном порядке.Язык автоматически удаляет объекты, если не выполнить специальные действия, как кучу или новое расположение.Например смарт-указатели как unique_ptr и shared_ptr, и контейнеры библиотеки стандартных шаблонов (STL), как vector, инкапсулируют newиdelete и new[]иdelete[] в объектах, которые имеют деструкторы.Вот почему так важно использовать смарт-указатели и контейнерах STL.
Другой важной концепцией управления временем существования: деструкторы.Деструкторы инкапсулируют освобождения ресурса.(Наиболее часто используемых является RRID, уничтожение является выпуск ресурсов.) Ресурс — это то, что получить из «система» и достаточно дать снова позже.Память является наиболее общих ресурсов, но также существуют файлы, сокеты, текстуры и другие ресурсы оперативной памяти. "-Владельца ресурса означает, что можно использовать, когда она нужна, но имеется также освободить его, когда вы закончите работу с ним.При удалении объекта его деструктора освобождает ресурсы, владельцем которых он является.
Окончательный понятие DAG (направленный Acyclic график).Структура владения в программе forms DAG.Объект не может владеть самим — это не только невозможно, но также по своей природе не имеет смысла.Но двух объектов можно использовать владение третий объект.Возможны несколько видов связи в DAG следующим образом: A является членом B (B владеет A), магазины c vector<D> (C владеет каждый элемент D), E магазинов shared_ptr<F> (E долей владения F, возможно с другими объектами), и т. д.Пока существует не циклов и представлены в DAG каждую ссылку в объекте, имеющий деструктор (вместо raw указатель, дескриптор или другого механизма), а затем утечки ресурсов невозможно, так как язык предотвращает их.Сразу же после них отпадает необходимость, без сборщик мусора выполняется освобождение ресурсов.Отслеживание времени жизни бесплатно накладные расходы для области стека, базовые классы, члены и связанные ошибки и дешево shared_ptr.
Время жизни на основе кучи
Время жизни объектов кучи, используйте смарт-указатели.Использование shared_ptr и make_shared как указатель по умолчанию и распределитель.Использование weak_ptr для приостановки выполнения циклов, выполнять кэширование и наблюдать объекты без влияния на или при условии, что-либо о времени их существования.
void func() {
auto p = make_shared<widget>(); // no leak, and exception safe
...
p->draw();
} // no delete required, out-of-scope triggers smart pointer destructor
Использование unique_ptr для уникальных владения, например, в pimpl идиом.(См. раздел Pimpl для инкапсуляции время компиляции (самомоднейшего C++)). Сделать unique_ptr основной целью все явные new выражения.
unique_ptr<widget> p(new widget());
Необработанных указателей можно использовать для наблюдения и без владельца.Указатель владеющий может dangle, но не может произойти утечка.
class node {
...
vector<unique_ptr<node>> children; // node owns children
node* parent; // node observes parent, which is not a concern
...
};
node::node() : parent(...) { children.emplace_back(new node(...) ); }
Когда требуется для оптимизации производительности может потребоваться использовать well-encapsulated -владельца указатели и явные вызовы для удаления.Например, при реализации структуру данных нижнего уровня.
Время жизни на основе стека
В современных C++ стековую область является мощным средством для написания надежного кода, так как она объединяет автоматическое стека жизни и время жизни члена данных с высокой эффективности — отслеживание времени жизни по существу свободных ресурсов.Время жизни объекта в куче требует тщательного управления вручную и может быть источником утечки ресурсов и снижению эффективности работы, особенно при работе с необработанных указателей.Рассмотрим этот код, который демонстрирует области на основе стека.
class widget {
private:
gadget g; // lifetime automatically tied to enclosing object
public:
void draw();
};
void functionUsingWidget () {
widget w; // lifetime automatically tied to enclosing scope
// constructs w, including the w.g gadget member
…
w.draw();
…
} // automatic destruction and deallocation for w and w.g
// automatic exception safety,
// as if "finally { w.dispose(); w.g.dispose(); }"
Экономно использовать время существования статической (статические глобальные, локальные статические функции), так как могут возникнуть проблемы.Что происходит, когда конструктор глобального объекта создает исключение?Как правило сбои приложения таким образом, что может быть трудно отлаживать.Порядок создания проблемных объектов время существования статической и не является типизированным параллелизма.Проблема, не только является создание объекта уничтожения заказа может быть сложным, особенно там, где участвует полиморфизма.Даже если объекта или переменной не полиморфных и не имеет сложные создания и уничтожения порядка, по-прежнему возникают проблемы параллелизма поточно ориентированными.Многопоточные приложения невозможно безопасно изменить данные в статических объектов без необходимости локальной памяти потока, блокировки ресурсов и другие специальные меры предосторожности.