Я использую std::unique_ptr
управлять непрозрачными типами из инфраструктуры CoreFoundation. CoreFoundation типы (иначе CFTypes
) должен быть выпущен вручную, поэтому мой рецепт std::unique_ptr
Тип выглядит так:
namespace detail {
template <typename CoreFoundationType>
struct cfreleaser {
constexpr cfreleaser() noexcept = default;
template <typename U> cfreleaser(cfreleaser<U> const&) noexcept {};
void operator()(CoreFoundationType __attribute__((cf_consumed)) cfp) {
if (cfp) { CFRelease(cfp); cfp = nullptr; }
}
};
template <typename CoreFoundationType>
using cfp_t = std::unique_ptr<
typename std::decay_t<
std::remove_pointer_t<CoreFoundationType>>,
cfreleaser<CoreFoundationType>>;
}
… эта договоренность позволяет мне отказаться от ручного выпуска CFType
ресурсы, например:
CGColorSpaceRef deviceRGB = CGColorSpaceCreateDeviceRGB();
/// … make use of `deviceRGB`
CGColorSpaceRelease(deviceRGB); /// release `deviceRGB`
… К схеме автоматического выпуска, вот так:
detail::cfp_t<CGColorSpaceRef> deviceRGB(CGColorSpaceCreateDeviceRGB());
/// … make use of `deviceRGB`
/// … `deviceRGB` releases automatically on scope exit
… это означает, что я в конечном итоге освобождаю каждого из CFType
экземпляры, которые я создаю с CFRelease(…)
— никогда не использовать какую-либо специализированную функцию выпуска для этого CFType
(CGColorSpaceRelease(…)
в приведенном выше фрагменте).
В моем прочтении документы CoreFoundation — а также документы для CFType
рамки на основе как CoreGraphics — каждая пользовательская функция релизера, которую я видел, была написана как «эквивалент CFRelease
”(например)… Мой вопрос, есть ли исключения из этой общности? Другими словами, безопасно ли использовать CFRelease(…)
на любой и все CFType
случаи, как я делаю в этом случае с std::unique_ptr
?
Задача ещё не решена.
Других решений пока нет …