Время жизни объекта определяется его областью действия. Однако иногда нам нужно или полезно создавать объект, который живет независимо от области, в которой он был создан. В C ++ оператор new
используется для создания такого объекта. А для уничтожения объекта можно использовать оператор delete
. Объекты, созданные оператором new
, распределяются динамически, то есть распределяются в динамической памяти (также называемой heap или free store ). Таким образом, объект, созданный new
, будет продолжать существовать до тех пор, пока не будет явно уничтожен с использованием delete
.
Некоторые ошибки, которые могут возникнуть при использовании new
и delete
:
- Утечка объекта (или память): используйте
new
для выделения объекта и забудьте delete
объект.
- Преждевременное удаление (или свисающая ссылка ): удерживая другой указатель на объект,
delete
объект, а затем используйте другой указатель.
- Двойное удаление : попытка
delete
объекта дважды.
Как правило, переменные области видимости являются предпочтительными. Однако RAII может использоваться в качестве альтернативы new
и delete
, чтобы заставить объект жить независимо от его области видимости. Такая техника состоит в том, чтобы взять указатель на объект, который был выделен в куче, и поместить его в объект handle / manager . У последнего есть деструктор, который позаботится об уничтожении объекта. Это будет гарантировать, что объект доступен для любой функции, которая хочет получить к нему доступ, и что объект будет уничтожен, когда закончится время жизни объекта дескриптора , без необходимости явной очистки.
Примеры из стандартной библиотеки C ++, использующей RAII: std::string
и std::vector
.
Рассмотрим этот кусок кода:
void fn(const std::string& str)
{
std::vector<char> vec;
for (auto c : str)
vec.push_back(c);
// do something
}
когда вы создаете вектор и помещаете в него элементы, вам не нужно выделять и освобождать такие элементы. Вектор использует new
, чтобы выделить место для своих элементов в куче, и delete
, чтобы освободить это пространство. Вы как пользователь вектора не заботитесь о деталях реализации и будете доверять вектору, чтобы он не просочился. В этом случае вектором является объект дескриптора его элементов.
Другими примерами из стандартной библиотеки, использующей RAII, являются std::shared_ptr
, std::unique_ptr
и std::lock_guard
.
Другое название этого метода - SBRM , сокращение от Управление ресурсами, связанными с областью действия .