나는 아직도 shared_ptr과 함께 커스텀 deleter를 사용하는 적절한 방법에 대해서 다소 혼란 스럽다. 나는 자원 할당의 트랙을 유지하는 ResourceManager에 클래스가 있고, 나는 릴리스 방법은 개인 만들어 사용하는 자원의 자동 릴리스를 지원하고, ResourceHolder 반환 방법을 할당하기 위해 인터페이스를 수정 :사용자 정의 shared_ptr deleter를 올바르게 사용하는 방법은 무엇입니까?
// 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()이 예외를 throw 할 수 있다면 어떻게됩니까? 어떤 상황에서 범위를 벗어나게하거나, 항상 예방해야합니까?
내 ResourceManager에는 사용중인 추적 라이브러리에 대한 종속성이 없으므로 호출자가 해당 생성자를 통해 제공 할 수있는 콜백을 선택했으며 릴리스 방법에서 호출되는 콜백을 선택했습니다.
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; } }
이 사운드 디자인 접근 방식 : 그래서 내 릴리스는 다음과 같이 보이는?
_ "건전한 설계 방법입니까?"_ - 아니요. '해제'는 객체 파괴와 관련하여 호출 할 수 있습니다. 예외가 이미 진행 중이므로이 단계에서 발생하는 예외가 주요 문제 일 수 있습니다. –
그러나 try catch 블록의 모든 것을 래핑하고 notback()을 콜백으로 만드는 것은 괜찮을까요? –