所以我正在阅读Handle in C上的文章并意识到我们将句柄实现为无效指针所以"无论如何"我们得到的对象/数据类型我们可以将void指针强制转换为那种Object / data并获取其值。所以我基本上有两个问题:
1.如果从以下Handle in C
中取得示例,请说明 typedef void* HANDLE;
int doSomething(HANDLE s, int a, int b) {
Something* something = reinterpret_cast<Something*>(s);
return something->doit(a, b);
}
如果我们将值传递给函数dosomething(21,2,2)
,那么这意味着HANDLE指向的值是21,如果是,当我们键入任何对象时它是如何将它转换为该对象的,它是否能够使用它,就像在这个例子中一样,所以在其他词中,指向对象Something something
的指针将存储值21。
2.其次,该链接也表示&#34;因此,在您的代码中,您只需将HANDLE作为不透明的值传递给#34;它到底意味着什么?为什么我们通过处理&#34;?如果有人能给出更有说服力的句柄示例,那么使用的对象就会很棒!
答案 0 :(得分:2)
1:句柄是对象的标识符。自&#34; 21&#34;不是对象,只是一个数字,你的函数调用是无效的。您的代码仅在&{39; s
&#39;真的指向Something
类型的结构。简单来说,一个句柄就像一个指针只不过是一个内存地址,因此&#34; 21&#34;将被解释为内存地址,如果你尝试写入它将会崩溃程序
2:&#34;不透明的价值&#34;意味着没有使用您的代码的开发人员不能对句柄识别的对象的内部结构做任何假设。这是一个优于指向结构的指针的优势,开发人员可以查看结构并采取一些在更改代码后不再适用的假设。 &#34;四处走动&#34;简单地表示:分配它并将其用作函数调用参数,如:
HANDLE s = CreateAnObject();
DoSomethingWithObject( s );
HANDLE t = s;
等
顺便说一句:在实际代码中,您应该为对象提供不同的名称,如EMPLOYEE_HANDLE,ORDER_HANDLE等。 句柄的典型示例是Windows中的窗口句柄。他们识别窗口,而不向您提供有关如何使用窗口的信息。构建了操作系统中的内存结构,因此微软能够改变这种内部结构,而不会有通过更改&#34; Window&#34;来破坏其他开发人员代码的风险。结构
答案 1 :(得分:1)
如果我们将值传递给函数dosomething(21,2,2),那是否意味着HANDLE指向的值为21,
没有。它只是意味着void*
的值为21.如果将21视为指向类型为Something
的对象的指针的值,则很可能会导致未定义的行为。
2.其次,该链接还说“所以在你的代码中你只是将HANDLE作为一个不透明的值传递”它实际上意味着什么?为什么我们“通过处理”?如果有人能给出更有说服力的句柄示例,那么使用的对象就会很棒!
手柄是不透明的,因为你无法通过它看到任何东西。如果句柄由void*
表示,则无法看到有关该对象的任何内容,因为无法取消引用void*
。如果句柄由int
表示(作为代码中其他位置定义的某个数组的索引),则无法查看句柄的值并了解相应对象所代表的内容。
理解句柄的唯一方法是使用适合句柄类型的方法将其转换为指针或引用。
如果句柄由void*
表示,则您发布的代码说明了如何提取指向具体对象的指针并理解该对象。
如果句柄由int
表示,您可能会看到以下内容:
int doSomething(HANDLE s, int a, int b) {
// If the value of s is 3, something will be a reference
// to the fourth object in the array arrayOfSomethingObjects.
Something& something = arrayOfSomethingObjects[s];
return something.doit(a, b);
}
答案 2 :(得分:1)
我没有意识到有一篇关于HANDLEs的事实性文章或者一种实现它们的事实方法。它们通常是一个windows构造,可以通过1985年某些开发人员决定实现它们的方式实现。
它真的具有和#34; thingy&#34;或者更确切地说&#34;可以用来获取资源的东西&#34;
不要养成创建自己的&#34;句柄的习惯。当然不要试图模仿1985年的代码习惯用法。如果可能的话,Void指针,reinterpret_casts和HANDLE都应该不惜一切代价避免。
你唯一需要处理的事情&#34; HANDLE&#34;是在使用Windows API时,文档将告诉您如何处理它。
在现代C ++中,如果要传递对象,请使用引用,指针和智能指针(包括unique_ptr,shared_ptr,weak_ptr)并研究调用哪些场景。