请问:句柄和指针,比如 HWND 和 CWnd* ,到底有什么区别?什么时候该用句柄,什么时候该用指针?

解决方案 »

  1.   

    不是吧~
    这有什么疑问?
    看MSDN中说明啊~
      

  2.   

    msdn中有很详细的说明
    句柄不是指针,但是你可以把它看成指针,它是唯一标示窗口的数码。他如何产生
    系统知道,我不知道。
      

  3.   

    既然选择了VC,就要多看MSDN。
      

  4.   

    我记得我以前不懂的时候,有一个大概是这样回答的:
    因为windows是一个多任务的系统,而且系统的内存是可以移动的。一个指针所指的内存区域随时可能被移走或被换到硬盘空间,于是系统在系统的内存区用句柄来标识系统核心对象(窗口、画刷、笔、内存等)。一旦这个对象被移走,只要修改这个数字就可以了。而指针是用来标识C++对象的。比如说在CWnd类里有一个成员叫m_hWnd,这就是窗口句柄。而pWnd只是间接使用CWnd类的成员函数来使用句柄。
    大概就是这个意思吧,表达得不好,希望你能明白。
      

  5.   

    谢谢大家。这是我从前面的帖子里找出来的,和stoneyrh说得差不多,个人觉得很有道理:在windows程序设计中,句柄仅是一个应用程序用来识别某些事情的数字如果想更透彻一点地认识句柄,我可以告诉大家,句柄是一种指向指针的指针。我们知 
    道,所谓指针是一种内存地址。应用程序启动后,组成这个程序的各对象是住留在内的 
    。如果简单地理解,似乎我们只要获知这个内存的首地址,那么就可以随时用这个地址 
    访问对象。但是,如果您真的这样认为,那么您就大错特错了。我们知道,Windows是一 
    个以虚拟内存为基础的操作系统。在这种系统环境下,Windows内存管理器经常在内存中 
    来回移动对象,依此来满足各种应用程序的内存需要。对象被移动意味着它的地址变化 
    了。如果地址总是如此变化,我们该到哪里去找该对象呢? 
        为了解决这个问题,Windows操作系统为各应用程序腾出一些内存储地址,用来专门 
    登记各应用对象在内存中的地址变化,而这个地址(存储单元的位置)本身是不变的。Wi 
    ndows内存管理器在移动对象在内存中的位置后,把对象新的地址告知这个句柄地址来保 
    存。这样我们只需记住这个句柄地址就可以间接地知道对象具体在内存中的哪个位置。 
    这个地址是在对象装载(Load)时由系统分配给的,当系统卸载时(Unload)又释放给系统 
    。 
    句柄地址(稳定)→记载着对象在内存中的地址────→对象在内存中的地址(不稳定) 
    →实际对象 
        但是,必须注意的是程序每次从新启动,系统不能保证分配给这个程序的句柄还是 
    原来的那个句柄,而且绝大多数情况的确不一样的。假如我们把进入电影院看电影看成 
    是一个应用程序的启动运行,那么系统给应用程序分配的句柄总是不一样,这和每次电 
    影院售给我们的门票总是不同的一个座位是一样的道理。 
      

  6.   

    其实我个人有一个不好的习惯:遇到问题,第一反应就是去问别人,或者找中文资料;MSDN只是偶然看看。我想以后的多看看了。
      

  7.   

    句柄用来引用不同的windows对象。你可以对窗口、文件使用句柄,也能对分配了的内存、图象使用句柄。可以把句柄理解为与指针类似。你必须通过某种方式来创建句柄;而且在使用完后销毁掉,不然将造成资源泄漏而使你的系统瘫痪。所以要保证它们在某个时候被销毁了。句柄术语一般用来指获取另一个对象的方法——一个广义的假指针。这个术语是(故意的)含糊不清的。 含糊不清在实际中的某些情况下是有用的。例如,在早期设计时,你可能不准备用句柄来表示。你可能不确定是否将一个简单的指针或者引用或者指向指针的指针或者指向引用的指针或者整型标识符放在一个数组或者字符串(或其它键)以便能够以哈希表(hash-table)(或其他数据结构)或数据库键或者一些其它的技巧来查询。如果你只知道你会需要一些唯一标识的东西来获取对象,那么这些东西就被称为句柄。 因此,如果你的最终目标是要让代码唯一的标识/查询一个Fred类的指定的对象的话,你需要传递一个Fred句柄这些代码。句柄可以是一个能被作为众所周知的查询表中的键(key)来使用的字符串(比如,在std::map<std::string,Fred> 或 std::map<std::string,Fred*>中的键),或者它可以是一个作为数组中的索引的整数(比如,Fred* array = new Fred[maxNumFreds]),或者它可以是一个简单的 Fred*,或者它可以是其它的一些东西。
    初学者常常考虑指针,但实际上使用未初始化的指针有底层的风险。例如,如果Fred对象需要移动怎么办?当Fred对象可以被安全删除时我们如何获知?如果Fred对象需要(临时的)连续的从磁盘获得怎么办?等等。这些时候的大多数,我们增加一个间接层来管理位置。例如,句柄可以是Fred**,指向Fred*的指针可以保证不会被移动。当Fred对象需要移动时,你只要更新指向Fred*的指针就可以了。或者让用一个整数作为句柄,然后在表或数组或其他地方查询Fred的对象(或者指向Fred对象的指针)。
    重点是当我们不知道要做的事情的细节时,使用句柄。 使用句柄的另一个时机是想要将已经完成的东西含糊化的时候(有时用术语magic cookie也一样,就像这样,“软件传递一个magic cookie来唯一标识并定位适当的Fred对象”)。将已经完成的东西含糊化的原因是使得句柄的特殊细节或表示物改变时所产生的连锁反应最小化。举例来说,当将一个句柄从用来在表中查询的字符串变为在数组中查询的整数时,我们可不想更新大量的代码。当句柄的细节或表示物改变时,维护工作更为简单(或者说阅读和书写代码更容易),因此常常将句柄封装到类中。这样的类常重载operator-> 和 operator*算符(既然句柄的效果象指针,那么它可能看起来也象指针)。 
      

  8.   

    msdn应该多看
    如果有小例子可以直接看例子一下就懂了