句柄是抽象对象(位图、套接字、文件、内存等)的标识符,用于识别受操作影响的对象:HBITMAP
、socket
、FILE*
是句柄的示例——它们实际上是整数,可能表示操作系统中某个表或映射中的索引。
严格来说,指针是内存中的一个精确位置。虽然指针有时用作句柄,但很少(如果有的话)反之亦然。
在面向对象的环境中,句柄被认为是低级实体,最好将句柄包装在对象中,该对象具有使用分配的句柄调用操作的方法。在这种情况下,您有一个对持有句柄的对象的引用,例如:CBitmap
、System.Net.Sockets.Socket
、std::fstream
等。
在不深入研究语言宗教战争的情况下,有些人会争辩说其中一种更清洁、更安全、更快、更容易。它几乎总是取决于你所处的环境——如果你有选择的话,建议你直接在 C# 中使用句柄,而在 C 中使用句柄会更简单(也是必要的)。
重要提示:在 .Net 环境中,如果您必须进行封送处理,您最终会读到一些关于被称为句柄的实际对象引用的内容。这是因为它们实际上是引擎盖下的句柄而不是指针。因此,当您在对象上调用方法时,编译器实际上是使用可以在内存中自由移动的对象的句柄调用该方法。这使得垃圾收集器可以避免内存碎片。因此,System.Drawing.Bitmap
您最终会得到一个指向句柄的指针的句柄。
编辑:
例如,C++ 中的 stdio/fstream:
// Read a short line from a file and output it to the console
// 256 bytes max for simplicity purposes
char buffer[256];
// With handle
FILE* file = fopen ("file.txt" , "r");
fgets(buffer, 256 , file);
std::cout << buffer << std::endl;
fclose (file);
// With object reference
{
std::ifstream stream ("file.txt");
stream.getline(buffer, 256);
std::cout << buffer << std::endl;
}
上面的例子使用了应该被认为是FILE*
文件句柄的东西。file
句柄是使用分配的,并fopen
传递给诸如fgets()
和之类的操作close()
。close()
释放句柄。
底部示例使用std::ifstream
. 句柄在对象构造函数中分配,并且在该对象内部。要对文件进行操作,请使用该对象提供的方法,例如getline()
. 当对象超出范围时,流析构函数会释放句柄,即在右括号处,或者如果对象是在堆上分配的,则需要显式删除它。