Я все еще немного запутался в правильном способе использования пользовательского делетера с shared_ptr. У меня есть класс ResourceManager, который отслеживает распределения ресурсов, и я изменил свой интерфейс для поддержки автоматического освобождения используемых ресурсов, делая метод Release частное и Выделяют метод возвращения ResourceHolder:Как правильно использовать пользовательский деблокиратор shared_ptr?
// ResourceManager.cpp:
public:
ResourceHolder<Resource> Allocate(args);
private:
void Release(Resource*);
И в ResourceHolder класса I реализовать так:
// ResourceHolder.h
template <typename T>
class ResourceHolder
{
public:
ResourceHolder(
_In_ T* resource,
_In_ const std::function<void(T*)>& cleanupFunction)
: _cleanupFunction(cleanupFunction)
, _resource(resource, [&](T* resource)
{
cleanup(resource);
}) // Uses a custom deleter to release the resource.
{
}
private:
std::function<void(T*)> _cleanupFunction;
std::shared_ptr<T> _resource;
};
// ResourceManager::Allocate()
...
return ResourceHolder<Resource>(new Resource(),[this](Resource* r) { Release(r); });
в моем методе очистки, я должен удалить T? Всегда ли это безопасно?
if (nullptr != T) delete T;
Что произойдет, если cleanup() может выдать исключение? Могу ли я позволить этому избежать каких-либо условий при определенных обстоятельствах или я всегда должен его предотвращать?
My ResourceManager не имеет зависимости от библиотеки трассировки, которую я использую, поэтому я выбрал обратный вызов, который вызывающий может предоставить через свой конструктор, и который будет вызван в методе release. Так что мой релиз выглядит следующим образом:
void Release(Resource* r) { shared_ptr<std::Exception> exc = nullptr; try { // Do cleanup. } catch(Exception* ex) { exc.reset(ex); } if (nullptr != r) delete r; // Is it now safe to throw? if (nullptr != m_callback) m_callback(args, exc); } void Callback(args, shared_ptr<std::Exception> ex) { // Emit telemetry, including exception information. // If throwing here is ok, what is the correct way to throw exception here? if (nullptr != ex) { throw ex; } }
Является ли это подход к разработке звука?
_ «Является ли это обоснованным проектом?» _ - «Выпуск» можно вызывать в контексте уничтожения объектов. Так как исключение уже существует, исключение, происходящее на этом этапе, может быть серьезной проблемой. –
Но обернуть все в блок catch try и сделать Callback a nothow() будет в порядке? –