当前位置:编程学习 > C/C++ >>

C++中句柄

一、句柄的概念
 
1.windows方面理解:
句柄,是整个windows编程的基础。
一个句柄是指使用的一个唯一的整数值,即一个四字节长的数值,来标志应用程序中的不同对象和同类对象中的不同的实例,诸如,一个窗口,按钮,图标,滚动条,输出设备,控件或者文件等。
应用程序能够通过句柄访问相应的对象的信息,但是句柄不是一个指针,程序不能利用句柄来直接阅读文件中的信息。如果句柄不用在I/O文件中,它是毫无用处的。 
句柄是windows用来标志应用程序中建立的或是使用的唯一整数,windows使用了大量的句柄来标志很多对象。
2.本人理解:
C++句柄是一种指向指针的指针。
C++句柄类的主要目的是在对象层面上实现多态。
二、实例详细说明
 
1.在visual studio 2010 创建控件器平台:
 
 
 
 
2.添加两个类,helloA,helloB
helloA.h
[cpp] 
#pragma once  
class helloA  
{  
public:  
    helloA(void);  
    ~helloA(void);  
    virtual void func()const{printf("A");}  
};  
helloB.h
[cpp]  
#pragma once  
#include "helloa.h"  
class helloB :  
    public helloA  
{  
public:  
    helloB(void);  
    ~helloB(void);  
     void func()const{printf("B");}  
};  
handel.cpp
[cpp]  
#include "stdafx.h"  
#include "helloA.h"  
#include "helloB.h"  
#include <vector>  
using namespace std;  
  
int _tmain(int argc, _TCHAR* argv[])  
{  
    vector<helloA> vec;  
    helloA a;  
    helloB b;  
    vec.push_back(a);  
    vec.push_back(b);  
      
    for ( vector<helloA>::iterator iter=vec.begin();iter!=vec.end();iter++)  
    {  
        (*iter).func();  
    }  
  
    return 0;  
}  
运行的结果:
 
 
 
原因:vec.push_back(b);  ,其实把截断了,将b转化为了它的基类helloA.
 
如何解决这个问题,可以用指针代替对象方法:如:vector<helloA*>vec;这样做可以达到多态的目的,但程序员必须接管内存管理,例如,更改下handel.cpp代码:
 
[cpp]  
vector<helloA*> vec;  
    helloA *a = new helloA;  
    helloB *b = new helloB;  
    vec.push_back(a);  
    vec.push_back(b);  
  
    for ( vector<helloA*>::iterator iter=vec.begin();iter!=vec.end();iter++)  
    {  
        (*iter)->func();  
    }  
 
运行结果:
 
 
 
 
效果达到,但问题来了,这里假如vec的生命周期结束了,vec不会主动释放b所占用的内存,如果不手动delete b,就会产生内存泄漏。
 
接下来,就实现下句柄类,来解决如上问题。
 
更改下helloA,helloB的代码:
helloA.h
[cpp]  
#pragma once  
class helloA  
{  
public:  
    helloA(void);  
    ~helloA(void);  
    virtual void func()const{printf("A");}  
    virtual helloA* clone() const {return new helloA(*this);}  
};  
helloB.h
[cpp] 
#pragma once  
#include "helloa.h"  
class helloB :  
    public helloA  
{  
public:  
    helloB(void);  
    ~helloB(void);  
     void func()const{printf("B");}  
     virtual helloB* clone() const{return new helloB(*this);}  
};  
同时,添加sample类,记得把sample.cpp的代码注释掉,我们只在sample头文件更改代码即可。
sample.h
[cpp]  
#pragma once  
#include "helloA.h"  
#include "helloB.h"  
#include <stddef.h>  
class sample  
{  
public:  
  
    sample():p(0),use(1){};  
    sample(const helloA& a):p(a.clone()),use(1){};  
    sample(const sample&i):p(i.p),use(i.use){use++;}  
    ~sample(){decr_use();};  
    sample& operator = (const sample& i)  
    {  
        use++;  
        decr_use();  
        p = i.p;  
        use = i.use;  
        return *this;  
    }  
    const helloA *operator->() const {if (p)return p;}  
  
    const helloA &operator*() const{if(p)return *p;}  
private:  
    helloA* p;  
    size_t use;  
    void decr_use(){if (-use == 0)delete p;}  
};  
回到main函数,更改代码
handle.cpp
[cpp] 
// handle.cpp : 定义控制台应用程序的入口点。  
//  
  
#include "stdafx.h"  
#include "helloA.h"  
#include "helloB.h"  
#include "sample.h"  
#include <vector>  
#include <list>  
using namespace std;  
  
  
int _tmain(int argc, _TCHAR* argv[])  
{  
  
    vector<sample> vec;  
    helloA a;  
    helloB b;  
  
    sample sample1(a);  
    sample sample2(b);  
  
    vec.push_back(sample1);  
    vec.push_back(sample2);  
  
      
    for ( vector<sample>::iterator iter=vec.begin();iter!=vec.end();iter++)  
    {  
        (*iter)->func();  
    }  
  
    return 0;  
}  
 
 
 
 
 
我们得到了正确的输出,如同sha
补充:软件开发 , C++ ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,