unique_ptr 作为通用处置对象
unique_ptr as general purpose dispose object
假设我有一种情况,我有一个提供特定接口的 SDK,这意味着一些手动资源管理或状态更改。它应该像这样使用:
// SDK has state B by default
SDK->setStateA();
something();
requiring();
stateA();
SDK->setStateB();
将状态更改封装为 unique_ptr 对象的自定义 allocator/deleter 是个好主意,或者,通过一些手动 Dispose 模式实现来获得此行为可能会更好。
既然不是资源分配,我就存疑了。这可能会引起混淆并使代码变得晦涩难懂。
我的另一个问题是我需要来自初始化和清理步骤的 return 代码。我可以使用 lambda 并通过捕获获取它们,但它看起来更加神秘。
也许有人已经尝试过并在一段时间后看到它如何使代码看起来像?
一般来说,代码的界面最好设计成易于使用和直观的方式,或者换句话说,不易被错误使用。特别是如果接口能够通过拒绝编译来防止bug,可以节省很多调试时间。
实现这种接口的一种可能性是与 std::mutex
<---> std::unique_lock
机制松散相关的东西:
class state_guard {
std::unique_ptr<SDK_type>& SDK;
state_guard(std::unique_ptr<SDK_type>& s) : SDK{ s } {
SDK->setStateA();
}
~state_guard() {
SDK->setStateB();
}
};
void something(state_guard&, ...);
void requiring(state_guard&, ...);
void stateA(state_guard&, ...);
std::unique_ptr<SDK_type> SDK{ get_sdk() };
{
state_guard guard{ SDK };
something(guard, ...);
requiring(guard, ...);
stateA(guard, ...);
}
通过强制将守卫作为函数参数传递(即使它在相应的函数中未使用),用户不能忘记设置为 stateA(感谢 RAII,将其重置为 stateB)。
假设我有一种情况,我有一个提供特定接口的 SDK,这意味着一些手动资源管理或状态更改。它应该像这样使用:
// SDK has state B by default
SDK->setStateA();
something();
requiring();
stateA();
SDK->setStateB();
将状态更改封装为 unique_ptr 对象的自定义 allocator/deleter 是个好主意,或者,通过一些手动 Dispose 模式实现来获得此行为可能会更好。
既然不是资源分配,我就存疑了。这可能会引起混淆并使代码变得晦涩难懂。
我的另一个问题是我需要来自初始化和清理步骤的 return 代码。我可以使用 lambda 并通过捕获获取它们,但它看起来更加神秘。
也许有人已经尝试过并在一段时间后看到它如何使代码看起来像?
一般来说,代码的界面最好设计成易于使用和直观的方式,或者换句话说,不易被错误使用。特别是如果接口能够通过拒绝编译来防止bug,可以节省很多调试时间。
实现这种接口的一种可能性是与 std::mutex
<---> std::unique_lock
机制松散相关的东西:
class state_guard {
std::unique_ptr<SDK_type>& SDK;
state_guard(std::unique_ptr<SDK_type>& s) : SDK{ s } {
SDK->setStateA();
}
~state_guard() {
SDK->setStateB();
}
};
void something(state_guard&, ...);
void requiring(state_guard&, ...);
void stateA(state_guard&, ...);
std::unique_ptr<SDK_type> SDK{ get_sdk() };
{
state_guard guard{ SDK };
something(guard, ...);
requiring(guard, ...);
stateA(guard, ...);
}
通过强制将守卫作为函数参数传递(即使它在相应的函数中未使用),用户不能忘记设置为 stateA(感谢 RAII,将其重置为 stateB)。