• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            拂曉·明月·彎刀

            觀望,等待只能讓出現(xiàn)的機(jī)會(huì)白白溜走

              C++博客 :: 首頁(yè) ::  :: 聯(lián)系 :: 聚合  :: 管理 ::
                在Windows編程中,GDI資源的泄露一直是需要引起C++程序員的高度關(guān)注,一不小心,就會(huì)在函數(shù)的中途正常退出或者中途拋出異常退出的地方遺忘掉釋放前面申請(qǐng)的資源。本人也曾多次碰到這種問(wèn)題,查閱了網(wǎng)上的資料,總是不能得到滿(mǎn)意的解決。最近看了下boost中的庫(kù),才略有收獲,也算是拋磚引玉吧。
                要想解決上面的問(wèn)題,就必須實(shí)現(xiàn)資源的自動(dòng)釋放,類(lèi)的析構(gòu)函數(shù)正好可以滿(mǎn)足此要求,就象標(biāo)準(zhǔn)庫(kù)中智能指針就是這么實(shí)現(xiàn)的,但問(wèn)題在于我們的參數(shù)個(gè)數(shù),參數(shù)類(lèi)型的不確定性。雖然重載和模板可以解決此問(wèn)題(這也是我在網(wǎng)上看到的解決方法),但模板類(lèi)的參數(shù)不具備自動(dòng)推導(dǎo)能力(經(jīng)傳入成員函數(shù)參數(shù)值推導(dǎo)出模板參數(shù)類(lèi)型),而且過(guò)多的模板偏特化也不是我所擅長(zhǎng)的,最主要是代碼的移植性無(wú)法保證。
                本文主要利用的boost中的bind庫(kù),覺(jué)得仿函數(shù)的功能跟自己當(dāng)前的需求不遠(yuǎn)了,因?yàn)樗鼈兊墓餐c(diǎn)有:
            1. 可以接收任意多個(gè)模板參數(shù)(沒(méi)有具體驗(yàn)證,至少是9個(gè)吧),
            2. 可以利用函數(shù)對(duì)模板參數(shù)類(lèi)型的推導(dǎo)能力,省去了參數(shù)類(lèi)型的指定。
            唯一不同的是bind后的仿函數(shù)是立即執(zhí)行,不能具有類(lèi)的析構(gòu)函數(shù)自動(dòng)執(zhí)行的優(yōu)點(diǎn)。目前需要解決的問(wèn)題是推遲執(zhí)行期,也既把operator()函數(shù)移到析構(gòu)函數(shù)中執(zhí)行,這就需要保存boost::bind(....)返回的對(duì)象,通過(guò)類(lèi)的構(gòu)造函數(shù)去保存,然后在析構(gòu)函數(shù)中執(zhí)行operator()就可以了。
                思路是出來(lái)了,但問(wèn)題是boost::bind(...)函數(shù)返回的類(lèi)型不確定,對(duì)象通過(guò)類(lèi)模板是可以保存,但類(lèi)沒(méi)有自動(dòng)推導(dǎo)能力,還是無(wú)法實(shí)現(xiàn),這里我就利用了boost::any的原理,正好解決了此問(wèn)題,而且它也可以用于函數(shù)的延遲執(zhí)行。詳見(jiàn)以下使用方法:
            步驟1: 實(shí)現(xiàn)類(lèi)似于boost:;any的類(lèi),主要完成資源的自動(dòng)釋放。實(shí)現(xiàn)如下:
            //SrcRelease.h頭文件
             1#ifndef _SRCRELEASE_INC_
             2#define _SRCRELEASE_INC_
             3
             4class CSrcRelease
             5{
             6public
             7    template<typename T>
             8    CSrcRelease(const T & value)
             9        : m_pHelder(new Helder<T>(value))
            10    {
            11    }

            12
            13    ~CSrcRelease()
            14    {
            15        delete m_pHelder;
            16    }

            17
            18private
            19    class IHelder
            20    {
            21    public:
            22        virtual ~IHelder() {}
            23    }
            ;
            24
            25    template<typename T>
            26    class Helder : public IHelder
            27    {
            28    public
            29        Helder(const T & value)
            30            : held(value)
            31        {
            32        }

            33        ~Helder() 
            34        {
            35            held();
            36        }

            37
            38    public// representation
            39        T held;
            40    }
            ;
            41
            42    IHelder* m_pHelder;
            43}
            ;
            44
            45#endif //_SRCRELEASE_INC_ 
            46

            步驟2: 下載boost庫(kù),因?yàn)橹挥玫搅薭oost::bind庫(kù),所以無(wú)需編譯. 將頭文件目錄加入vs2005中。
            步驟3: 客戶(hù)端調(diào)用
            //main.cpp
             1#include "SrcRelease.h"
             2#include <iostream>
             3#include <Windows.h>
             4#include <boost/bind.hpp>
             5#include <cassert>
             6
             7void _stdcall InvokeStr(const char* szValue)
             8{
             9    std::cout<<szValue<<std::endl;
            10}

            11
            12bool _stdcall InvokeStr(const char* szValue, int a, int b)
            13{
            14    std::cout<<szValue<<"\ta: "<<a<<"\tb: "<<b<<std::endl;
            15    return true;
            16}

            17
            18int main()
            19{
            20    //由于API都是_stdcall調(diào)用,而vs2005環(huán)境都是默認(rèn)_cdecl,所以需要修改vs2005環(huán)境
            21    HBITMAP hBitmap=reinterpret_cast<HBITMAP>(LoadImage(NULL, L"test.bmp", IMAGE_BITMAP, 00, LR_LOADFROMFILE));
            22    assert(hBitmap!=NULL);
            23    CSrcRelease aBitmapRelease(boost::bind(&DeleteObject, hBitmap));
            24
            25    std::cout<<"Invoke Outer Before"<<std::endl;
            26    CSrcRelease aRelease(boost::bind(&InvokeStr, "Invoke Outer After"85));
            27
            28    {
            29        std::cout<<"Invoke Inner Before"<<std::endl;
            30        CSrcRelease aRelease(boost::bind(&InvokeStr, "Invoke Inner After"));
            31        std::cout<<"Invoke Inner Middle"<<std::endl;
            32    }

            33
            34    std::cout<<"Invoke Outer Middle"<<std::endl;
            35    return 0;
            36}
             

            以上代碼在winxp+vs2005下測(cè)試通過(guò),如有疑問(wèn),歡迎聯(lián)系: ietj@mail.21cn.com
             
                                                                        嘵月刀
                                                                        2008.3.5
            posted on 2009-10-23 14:50 一路風(fēng)塵 閱讀(1388) 評(píng)論(1)  編輯 收藏 引用 所屬分類(lèi): C++技術(shù)/工作總結(jié)

            評(píng)論

            # re: C++ 資源釋放 2009-11-13 01:23 OwnWaterloo
            any會(huì)使用動(dòng)態(tài)內(nèi)存,效率比較低。而且,你也不希望看到如下代碼:
            CSrcRelease ... 產(chǎn)生異常吧?

            可以用function<void ()>來(lái)保存bind的結(jié)果,并在析構(gòu)函數(shù)中調(diào)用。
            或者,使用Loki::ScopeGuard。

              回復(fù)  更多評(píng)論
              

            久久精品亚洲中文字幕无码麻豆| 欧美大香线蕉线伊人久久| 久久中文字幕一区二区| 久久91精品国产91久久麻豆| 国产精品女同久久久久电影院| 久久精品国产亚洲av水果派 | 亚洲va中文字幕无码久久| 无码超乳爆乳中文字幕久久| 久久成人国产精品| 久久国产影院| 婷婷伊人久久大香线蕉AV| 国内精品久久久久久中文字幕| 日本高清无卡码一区二区久久| 蜜臀av性久久久久蜜臀aⅴ麻豆 | 少妇精品久久久一区二区三区| 久久久久人妻精品一区| 精品久久久无码人妻中文字幕豆芽 | 欧美日韩精品久久免费| 久久嫩草影院免费看夜色| 久久精品亚洲日本波多野结衣| 狠狠色婷婷久久综合频道日韩| 久久久国产打桩机| 精品久久久久久亚洲| 国产一级持黄大片99久久| 久久精品国产亚洲Aⅴ香蕉| 精品午夜久久福利大片| 72种姿势欧美久久久久大黄蕉| 国产精品嫩草影院久久| 久久久久国色AV免费观看| 久久综合久久综合亚洲| 精品久久无码中文字幕| 国产精久久一区二区三区| 77777亚洲午夜久久多喷| 国产午夜免费高清久久影院| 久久成人精品视频| 国产精品久久久久久久久久影院 | 久久久久99这里有精品10| 色综合久久综合中文综合网| 97久久精品人妻人人搡人人玩 | 国产一区二区三区久久| 国产精品九九久久免费视频|