Вот статья, в которой говорится об идиоме под названием Rule of Zero.
Здесь выдержка:
class module {
public:
explicit module(std::wstring const& name)
: handle { ::LoadLibrary(name.c_str()), &::FreeLibrary } {}
// other module related functions go here
private:
using module_handle = std::unique_ptr<void, decltype(&::FreeLibrary)>;
module_handle handle;
};
Он повторно использует функции unique_ptr RAII, поэтому вам не нужно заботиться о реализации сложной и многоплодной обертки из правила пяти.
Представленный таким образом (управляя ресурсами на основе ручек с помощью unique_ptr, таким образом), это выглядит как взломать для меня, а не лучшее решение для того, что он пытается решить. Слишком много предположений подразумеваются неявно:
- Один из них способен сверять и использовать базовый тип, на который построен
#define(илиtypedef)HANDLE. Для меня это должно быть скрытое знание, и решение должно основываться исключительно на том, что делает интерфейс:HANDLE. - Ручки могут быть любыми, они не должны быть типами указателей.
Я бы хотел использовать эту идиому, но во многих ситуациях я наткнулся на нее.
Является ли эта обертка, сфокусированная на RAII, уже сделанной и полезной в какой-нибудь классной библиотеке? Все ли используют такой инструмент, и я не знаю? (Я считаю, что неплохо иметь такую оснастку не только для одного, но и для многих типов владельцев)
РЕДАКТИРОВАТЬ 1
Речь идет не о дескрипторах ресурсов платформы, например, glGenLists возвращает вид дескриптора, a GLuint, и вы должны называть glDeleteLists на нем. Как уже указывалось, ручками ресурсов не являются типы указателей, и это предположение не следует принимать.
EDIT 2
Правило Zero, в прежнем примере, с использованием уже существующего инструмента, unique_ptr, показывает как хороший ярлык для управления дескрипторами. Дополнительные предположения, которые он требует, заставляют его отстать. Правильные предположения состоят в том, что у вас есть дескриптор, и у вас есть функция уничтожения ресурсов, которая уничтожает ресурс, заданный дескриптором. Независимо от того, является ли дескриптор void *, a GLuint, что бы это ни было, это не имеет значения, и, что еще хуже, не нужно даже требовать сопоставить внутренний тип HANDLE. Для управления ручками RAII, если идиома говорит об этом хорошо и не может применяться в таких ситуациях, я считаю, что это не хорошо для этого, наконец, с данным инструментом.
РЕДАКТИРОВАТЬ 3
Иллюстративная ситуация была бы, скажем, вы отвечаете за использование новой сторонней библиотеки C. Он содержит FooHandle create_foo() и a void destroy_foo(FooHandle). Итак, вы думаете, "позвольте использовать FooHandle, используя правило нуля". Хорошо, вы идете с помощью unique_ptr, a unique_ptr к тому, что вы спрашиваете сами? Является FooHandle указателем?, так что вы используете unique_ptr to FooHandle не подвергаемый базовый тип? Это int?, так что вы можете использовать его прямо или лучше (re) typedef вещи, подобные @NicolBolas, сделали в его ответе. Для меня это кажется явным, даже в такой тривиальной ситуации, unique_ptr уже показывает, что он не идеально подходит для управления ручками ресурсов.
Отказ от ответственности:
Я попытался переформулировать и лучше выразить себя:
EDIT 4
Я нашел то, что искал, я поставил его как ответ в переформулированном вопросе: qaru.site/info/404574/....