- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
Windows 句柄有时很烦人,要记得在之后进行清理(使用创建的笔和画笔进行 GDI 就是一个很好的例子)。 RAII 解决方案很棒,但是为每种不同类型的 handle 制作一个完整的(五法则)RAII 类真的那么好吗?当然不是!我能看到的最好的是一个完整的通用 RAII 类,其他类只定义应该清理句柄时要做什么,以及其他特定于句柄的方面。
例如,一个非常简单的模块类可以这样定义(只是一个例子):
struct Module {
Module() : handle_{nullptr} {}
Module(HMODULE hm) : handle_{hm, [](HMODULE h){FreeLibrary(h);}} {}
operator HMODULE() const {return handle_.get();}
private:
Handle<HMODULE> handle_;
};
一切都很好,花花公子,不需要析构函数或任何东西。当然,能够将 Handle
类编写为不需要析构函数或其他任何东西也很好。为什么不使用现有的 RAII 技术?一种想法是使用指向 void
的智能指针,但这行不通。以下是正常情况下实际声明句柄的方式:
#define DECLARE_HANDLE(n) typedef struct n##__{int i;}*n
DECLARE_HANDLE(HACCEL);
DECLARE_HANDLE(HBITMAP);
DECLARE_HANDLE(HBRUSH);
...
它实际上区分句柄类型,这很好,但它使得使用指向 void
的智能指针变得不可能。相反,如果根据定义,句柄是指针,那么可以提取类型怎么办?
我的问题是以下假设是否安全。它使用必须关闭的桌面句柄。除了共享指针和唯一指针之间的差异(例如,FreeLibrary
有其自己的引用计数语义),假设句柄是一个指针并将智能指针指向它指向的任何内容,或者我不应该使用智能指针并使 Handle
本身实现 RAII 方面?
#include <memory>
#include <type_traits>
#include <utility>
#include <windows.h>
int main() {
using underlying_type = std::common_type<decltype(*std::declval<HDESK>())>::type;
std::shared_ptr<underlying_type> ptr{nullptr, [](HDESK desk){CloseDesktop(desk);}};
}
最佳答案
我相信所有 Windows 指针在技术上都是指向系统 Windows 内核部分内部对象的指针(或者有时,可能是指向由内核代码分配的用户端对象,或该主题的某些变体)。
我完全不相信您应该将它们视为指针。它们只是纯技术角度的指针。它们不再是“指针”,就像 C 风格的“FILE *”是指针一样。我不认为你会建议使用 shared_ptr<FILE*>
稍后处理关闭文件。
将句柄包装到稍后清理它的东西中绝对是个好主意,但我认为使用智能指针解决方案不是正确的解决方案。使用知道如何关闭 handle 的模板化系统将是理想的。
我想您还需要以某种适用于所有相关人员的好方法处理“我想将此句柄从这里传递到其他地方” - 例如你有一个以某种方式获取资源的函数,它返回这些资源的句柄——你是否返回一个已经包装的对象,如果是,拷贝如何工作?
如果您需要在使用另一个 handle 之前保存一个 handle 的拷贝(例如,保存当前笔,然后设置自定义笔,然后恢复)怎么办?
关于c++ - 依靠 Windows 句柄的类型作为指针可以吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16676701/
我设置了 Helm 柄和 Helm 柄。我有tiller-deploy。昨天,我可以定期运行了。但今天我收到此错误消息 Error: could not find a ready tiller pod
我以前已将分er安装到特定的 namespace 中。 我设置了一个环境变量来设置'tiller'命名空间-但我不记得该环境变量的名称-而且似乎无法通过网络搜索找到它。 这是什么 key ? 最佳答案
当我在 View 模型中使用如下界面时 class MainViewModel @ViewModelInject constructor( private val trafficImagesR
我正在尝试找到如何在某个 fragment 相关场景中定义 Hilt 的解决方案。我有以下设置: Activity 父 fragment 1 子 fragment 1 子 fragment 2 ...
Hilt 指出如果没有@Provides 注解就不能提供这个接口(interface): interface PlannedListRepository { fun getAllLists()
我的问题非常简单明了:两个注释/示例之间有什么区别: 例子一 @Singleton class MySingletonClass() {} @Module @InstallIn(FragmentCom
我是一名优秀的程序员,十分优秀!