智能指针介绍

智能指针是为了解决程序员创建了资源而忘记释放造成内存泄漏的问题,可减少代码编写过程中的代码长度,减少程序员对资源管理的难度,因而在COM组件及各类插件中有广泛应用。
1、智能指针的原理
  智能指针的原理是利用对象在离开作用域时会调用对象的析构函数,将资源指针封装进类中,并将资源指针的释放过程写入析构函数中,这样就能在对象释放时自动释放资源。

一个管理注册表句柄的智能指针示例如下:

 

class CSPHKey : public CBase_Uncopy
{
private:
        HKEY        m_hKey;

public:
        CSPHKey(HKEY hKey) 
        {
                m_hKey = hKey;
        }        
        
        virtual        ~CSPHKey() 
        {
                RegCloseKey(m_hKey);               
        }
}

 

2、智能指针的注意事项

   智能指针由于是用类对象实现的,所以如果有对象复制过程(如函数传值调用),会产生多个智能指针对象,对象释放的过程会多次在析构函数中释放资源,会造成不可预知的意外,故要防止这种情况发生,一般可采取禁止对象复制的方式或者采用引用计数的方式来解决这个问题,下面给出一个Effective C++中的例子,只要继承这个类即可防止对象被复制:

 

class CBase_Uncopy
{
protected:
        CBase_Uncopy() {}                        //允许继承对象的构造和析构
        ~CBase_Uncopy() {}
private:
        CBase_Uncopy(const CBase_Uncopy&);      //不允许拷贝构造
        CBase_Uncopy& operator = (const CBase_Uncopy&);     //不允许用另一个对象拷贝构造
};

 

3、完整的管理注册表句柄的智能指针示例

 

class CSPHKey : public CBase_Uncopy
{
private:
        HKEY        m_hKey;

public:
        CSPHKey(HKEY hKey) 
        {
                m_hKey = hKey;
        }        
        
        //无参构造函数
        CSPHKey() 
        {
                m_hKey = NULL;
        }

        virtual        ~CSPHKey() 
        {
                Close();                
        }

        //取hKey
        HKEY GetHKey()
        {
                return        m_hKey;
        }

        //关闭hKey
        LSTATUS Close()
        {
                LSTATUS        ls = ERROR_SUCCESS;
                if (m_hKey)
                {
                        ls = RegCloseKey(m_hKey);
                        m_hKey = NULL;                        
                }

                return        ls;
        }

        //重载*操作符,允许直接取hKey值
        operator HKEY() const
        {
                return        m_hKey;
        }
        
        //重载赋值操作符,允许直接用HKEY赋值
        void operator = (HKEY& hKey)
        {
                m_hKey = hKey;
        }

        //重载 & 操作符,允许取HKEY的指针
        HKEY* operator & ()
        {
                return        &m_hKey;
        }
};

由于重载了复制操作符和取值操作符,我们可以像使用HKEY一样对智能指针进行赋值,取址等操作。

 

 

CSPHKey shPluginKey;

//对智能指针取址
RegOpenKeyEx(HKEY_LOCAL_MACHINE, _("SoftWare\MozillaPlugins\test"), NULL, KEY_WRITE, &shPluginKey));

//使用智能指针替代HKEY句柄
ULONG ulData = 2;
RegSetValueEx(shPluginKey, _T("test"), NULL, REG_DOWRD, &ulData, sizeof(ulData));

 

 

我们还可以修改这个类,把Close改为其他资源释放的函数(如CloseHandle()),使其变成其他资源类型的智能指针。

转载于:https://www.cnblogs.com/organic/p/5005656.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值