C++ 是否有适当的';一揽子所有权';对于';手柄';有空吗?

C++ 是否有适当的';一揽子所有权';对于';手柄';有空吗?,c++,c++11,handle,raii,ownership-semantics,C++,C++11,Handle,Raii,Ownership Semantics,具有正确的语义,而不是指针。因此,我举了一个这样的例子(摘自: 类模块{ 公众: 显式模块(std::wstring const&name) :handle{::LoadLibrary(name.c_str()),&::FreeLibrary}{} //其他与模块相关的功能都在这里 私人: 使用module_handle=std::unique_ptr; 模块_手柄; }; 使用unique_ptr作为句柄的“包中所有权”是一个坏例子。首先,它利用了句柄是指针类型的内部知识,并利用这一知识为“

具有正确的语义,而不是指针。因此,我举了一个这样的例子(摘自:

类模块{
公众:
显式模块(std::wstring const&name)
:handle{::LoadLibrary(name.c_str()),&::FreeLibrary}{}
//其他与模块相关的功能都在这里
私人:
使用module_handle=std::unique_ptr;
模块_手柄;
};
使用
unique_ptr
作为句柄的“包中所有权”是一个坏例子。首先,它利用了句柄是指针类型的内部知识,并利用这一知识为“不透明”句柄类型所构建的基本类型创建一个
唯一的\u ptr

句柄可以是任何类型,可以是指针,也可以是索引,谁知道呢。最重要的是,您手头上的(例如来自大多数C API)是一个句柄及其资源释放函数

在句柄语义中是否有合适的“包中所有权”?我的意思是,已经公开供一个人使用了?

对我来说,
unique\u ptr
等不起作用,我必须对句柄类型是什么做不必要的假设,而我只想通过不透明的句柄类型及其释放功能获得“包中的所有权”

一个人在句柄类型中窥视来根据这些信息进行构造是没有意义的。这是个把手,没关系

我将在这里引用另一位SO用户的感受:

创建一个特定的“智能指针”类,不会花费很长时间。不要辱骂 图书馆课程。句柄语义与 C++指针;首先,取消对句柄的引用毫无意义

使用自定义智能句柄类的另一个原因-NULL不适用 总是指一个空把手。有时它是无效的\u句柄\u值, 这是不一样的

免责声明:

这个问题重新制定并建立在这个问题之上:


类型
独特的\u ptr
没有短语“句柄”那么笼统,是的。但为什么不应该呢?只有一个“句柄”示例(例如,一个整数索引示例)与
unique\u ptr
一样通用。您无法将一种特定的句柄与“所有句柄”进行比较


如果您想要一个单一的、具体的C++类型(或类型模板),它是一个句柄而不实际定义任何特定的处理语义,那么…我帮不了你。我认为任何人都不可能做到。

我不同意你的前提
unique\u ptr
可能有点用词不当——它处理资源。
句柄
也处理资源。这是一个完美的匹配。我的前提不完全基于类型名…你到底有什么问题?您不喜欢名称
unique\u ptr
?@EtienDemartel:要将
unique\u ptr
用于非指针句柄,您需要一个特殊的deleter,它定义了嵌套的
指针类型,而
指针类型不能简单地说是
int
,因为
int
不符合
unique\u ptr
想要的空指针要求。然而,这会使任何东西适应那些可为空的指针要求。如果您愿意,您还可以添加一个转发到
*值的一元
运算符*
,以及一个
运算符->
,这样您就可以实际使用
*up
up->foo()
@Xeo:如果您要经历编写包装器的麻烦。。。为什么不编写一个适当的RAII对象,它可以保存任何值,并在该类型被销毁时调用给定的函数/函子?对于非指针对象,使用
unique\u ptr
比使用
unique\u ptr>要简单得多。说真的,为一个对象编写复制/移动构造函数并不是一个繁重的负担。它不太通用,因此应该在合适的地方使用。当一个人开始查找什么是
句柄
(应该是不透明的,句柄的主要特征之一),并在不太通用的工具中使用这些信息时,对我来说,这是一种难闻的气味。当然,可以断言
HANDLE
is
void*
对于我的例子,其他基于HANDLE的库呢,你会假设断言消失了吗?这个假设不是句柄语义的一部分,
handle
是不透明的。@chico:“其他基于句柄的库”有不同的句柄类型<代码>唯一\u ptr
是一种句柄类型。您在编码过程中遇到了什么实际问题?
unique\ptr
是一种句柄类型吗?我不知道你这是什么意思<代码>句柄
是句柄类型。我的实际问题是忽略使用
unique\u ptr
来管理所引用资源的生命周期是不透明的。我认为这是一个糟糕的做法,我要求一个众所周知的“所有权-一揽子计划”的选择,这样做是对的。我的意思是,不是像那样的违规封装。句柄类型是不透明的,一个好的工具会以同样的语法方式处理句柄,最后是整型和基于指针的。@chico:你一直说句柄类型必须是不透明的,但我看不出有什么原因
unique_ptr
对于具有指针语义的句柄来说非常合适。当然,它没有非指针语义。这是一种句柄,不管你是否认为句柄是不透明的,重要的是它们通常被认为是不透明的。您可以在内部将句柄类型构建为一个
void*
,并为您的客户预先断言它总是这样。您的客户端使用
unique\u ptr
非常安全(看起来
unique\u ptr
没有真正意义,您无法从句柄类型推断任何东西,它不是指向未类型化的指针)。但这是你的特殊手柄的情况。一般来说,这个过程不适用于句柄。为什么强制客户端手动
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;
};