- 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/
我正在尝试编写一个相当多态的库。我遇到了一种更容易表现出来却很难说出来的情况。它看起来有点像这样: {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE
谁能解释一下这个表达式是如何工作的? type = type || 'any'; 这是否意味着如果类型未定义则使用“任意”? 最佳答案 如果 type 为“falsy”(即 false,或 undef
我有一个界面,在IAnimal.fs中, namespace Kingdom type IAnimal = abstract member Eat : Food -> unit 以及另一个成功
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: What is the difference between (type)value and type(va
在 C# 中,default(Nullable) 之间有区别吗? (或 default(long?) )和 default(long) ? Long只是一个例子,它可以是任何其他struct类型。 最
假设我有一个案例类: case class Foo(num: Int, str: String, bool: Boolean) 现在我还有一个简单的包装器: sealed trait Wrapper[
这个问题在这里已经有了答案: Create C# delegate type with ref parameter at runtime (1 个回答) 关闭 2 年前。 为了即时创建委托(dele
我正在尝试获取图像的 dct。一开始我遇到了错误 The function/feature is not implemented (Odd-size DCT's are not implemented
我正在尝试使用 AFNetworking 的 AFPropertyListRequestOperation,但是当我尝试下载它时,出现错误 预期的内容类型{( “应用程序/x-plist” )}, 得
我在下面收到错误。我知道这段代码的意思,但我不知道界面应该是什么样子: Element implicitly has an 'any' type because index expression is
我尝试将 SignalType 从 ReactiveCocoa 扩展为自定义 ErrorType,代码如下所示 enum MyError: ErrorType { // .. cases }
我无法在任何其他问题中找到答案。假设我有一个抽象父类(super class) Abstract0,它有两个子类 Concrete1 和 Concrete1。我希望能够在 Abstract0 中定义类
我想知道为什么这个索引没有用在 RANGE 类型中,而是用在 INDEX 中: 索引: CREATE INDEX myindex ON orders(order_date); 查询: EXPLAIN
我正在使用 RxJava,现在我尝试通过提供 lambda 来订阅可观察对象: observableProvider.stringForKey(CURRENT_DELETED_ID) .sub
我已经尝试了几乎所有解决问题的方法,其中包括。为 提供类型使用app.use(express.static('public'))还有更多,但我似乎无法为此找到解决方案。 index.js : imp
以下哪个 CSS 选择器更快? input[type="submit"] { /* styles */ } 或 [type="submit"] { /* styles */ } 只是好
我不知道这个设置有什么问题,我在 IDEA 中获得了所有注释(@Controller、@Repository、@Service),它在行号左侧显示 bean,然后转到该 bean。 这是错误: 14-
我听从了建议 registering java function as a callback in C function并且可以使用“简单”类型(例如整数和字符串)进行回调,例如: jstring j
有一些 java 类,加载到 Oracle 数据库(版本 11g)和 pl/sql 函数包装器: create or replace function getDataFromJava( in_uLis
我已经从 David Walsh 的 css 动画回调中获取代码并将其修改为 TypeScript。但是,我收到一个错误,我不知道为什么: interface IBrowserPrefix { [
我是一名优秀的程序员,十分优秀!