• <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>

            chaosuper85

            C++博客 首頁(yè) 新隨筆 聯(lián)系 聚合 管理
              118 Posts :: 0 Stories :: 3 Comments :: 0 Trackbacks

                C++虛函數(shù)探索筆記(3)——延伸思考:虛函數(shù)應(yīng)用的一些其他情形

                關(guān)注問(wèn)題:

                虛函數(shù)的作用

                虛函數(shù)的實(shí)現(xiàn)原理

                虛函數(shù)表在對(duì)象布局里的位置

                虛函數(shù)的類(lèi)的sizeof

                純虛函數(shù)的作用

                多級(jí)繼承時(shí)的虛函數(shù)表內(nèi)容

                虛函數(shù)如何執(zhí)行父類(lèi)代碼

                多繼承時(shí)的虛函數(shù)表定位,以及對(duì)象布局

                虛析構(gòu)函數(shù)的作用

                虛函數(shù)在QT中的應(yīng)用

                虛函數(shù)與inline修飾符,static修飾符

                虛析構(gòu)函數(shù)

                大家都知道,在C++里需要自己嚴(yán)格管理好資源的分配和回收。通常情況下,

            在一個(gè)對(duì)象被析構(gòu)的時(shí)候,是要由其釋放其申請(qǐng)到的各種資源的。最常見(jiàn)的,當(dāng)

            然就是內(nèi)存資源啦。

                當(dāng)只有一個(gè)類(lèi)的時(shí)候,我們可以不用考慮太多,只要在析構(gòu)函數(shù)里檢查并釋

            放所有申請(qǐng)到的資源即可。但是在這個(gè)類(lèi)繼承了一個(gè)抽象接口基類(lèi)時(shí),就有點(diǎn)點(diǎn)

            不一樣了。讓我們看看類(lèi)的析構(gòu)過(guò)程:

                在大多數(shù)的類(lèi)的使用時(shí),通常都是直接刪除該類(lèi)的實(shí)例對(duì)象,然后該類(lèi)的析

            構(gòu)函數(shù)就會(huì)被調(diào)用,從而使得這個(gè)類(lèi)在析構(gòu)函數(shù)里執(zhí)行的資源釋放代碼被執(zhí)行到

                如果這個(gè)類(lèi)繼承了其他類(lèi),那么編譯器還會(huì)在這個(gè)類(lèi)的析構(gòu)函數(shù)里自動(dòng)添加

            對(duì)父類(lèi)的析構(gòu)函數(shù)的調(diào)用,從而將父類(lèi)里申請(qǐng)的資源也進(jìn)行釋放。如果偶多個(gè)父

            類(lèi),也會(huì)依次調(diào)用各個(gè)析構(gòu)函數(shù)。

                倘若繼承的是一個(gè)抽象接口類(lèi),并且在程序運(yùn)行期,可能通過(guò)一個(gè)基類(lèi)指針

            將此對(duì)象釋放掉,那么致命而又隱藏的內(nèi)存泄露BUG就出現(xiàn)啦……因?yàn)樵噲D刪除的

            是基對(duì)象,刪除時(shí)調(diào)用的是基類(lèi)的析構(gòu)函數(shù),而基類(lèi)的析構(gòu)函數(shù)當(dāng)然是不會(huì)去調(diào)

            用子類(lèi)的析構(gòu)函數(shù)的羅!

                讓我們看看下面的代碼,使用vs2008編譯并運(yùn)行的時(shí)候,將會(huì)在程序運(yùn)行結(jié)

            束時(shí)報(bào)告內(nèi)存泄漏情況(如果要在linux下編譯測(cè)試,需要去掉第一行的include

            ,以及return前的_CrtDumpMemoryLeaks()函數(shù),然后使用linux下檢查內(nèi)存泄

            露的工具進(jìn)行測(cè)試)。
             //Source filename: Win32Con.cpp
            #include
            class parent
            {
            public:
             parent() { }
             /*virtual */ ~parent() { }
            };

            class child:public parent
            {
            public:
             child()
             {
              p=new char[1000];
             }
             ~child()
             {
              delete[] p;
             }
             char *p;
            };

            void free_child(parent *pp)
            {
             delete pp;
            }

            int main()
            {
             child *obj=new child();
             free_child(obj);
             _CrtDumpMemoryLeaks();
             return 0;
            }

             


                在這段代碼里我們創(chuàng)建的是一個(gè)child類(lèi)型的對(duì)象,然后使用free_child

            (parent*)函數(shù)來(lái)試圖釋放這個(gè)對(duì)象,這個(gè)時(shí)候,只會(huì)調(diào)用到parent::

            ~parent()這個(gè)析構(gòu)函數(shù),而不會(huì)調(diào)用到child::~child()!

                如何解決這個(gè)問(wèn)題呢?

                很簡(jiǎn)單的,只要在parent::~parent()前增加 virtual關(guān)鍵字,將其變成

            一個(gè)虛函數(shù)。這樣,無(wú)論是以這個(gè)對(duì)象的父類(lèi)指針進(jìn)行刪除的時(shí)候,就會(huì)從虛函

            數(shù)表里定位到子類(lèi)child的析構(gòu)函數(shù),這樣就能夠從子類(lèi)開(kāi)始一級(jí)一級(jí)的向上調(diào)用

            析構(gòu)函數(shù),從而正確的將這個(gè)對(duì)象在各個(gè)繼承層次上申請(qǐng)的所有資源都釋放掉。

                正因?yàn)檫@個(gè)原因,在很多C++編程原則的文章或者書(shū)里都會(huì)提到這樣的原則:

                如果一個(gè)類(lèi)要被設(shè)計(jì)為可被繼承的基類(lèi),那么其析構(gòu)函數(shù)應(yīng)該被聲明為虛函

            數(shù)。

               虛函數(shù)在QT中的應(yīng)用

                在QT里虛函數(shù)的應(yīng)用非常的廣泛,事實(shí)上,在大多數(shù)的C++類(lèi)庫(kù)里都不可避免

            的要使用到虛函數(shù)。這里簡(jiǎn)單的列舉QT里使用虛函數(shù)的情況:

                QT的事件機(jī)制

                是使用了虛函數(shù)的,你因此才可以自定義事件處理函數(shù)。比如最核心的

            QObject類(lèi)的定義里(在qobject.h里),我們可以看到如下的虛函數(shù)定義:

                virtual bool event(QEvent *);

                virtual bool eventFilter(QObject *, QEvent *);

                然后,在QWidget類(lèi)繼承QObject類(lèi)后重新實(shí)現(xiàn)了上面的兩個(gè)虛函數(shù),完成很

            多窗口控件類(lèi)的缺省事件處理。

                當(dāng)你要編寫(xiě)自定義的QT控件的時(shí)候,對(duì)event虛函數(shù)的重新實(shí)現(xiàn)就更是重要啦

                QT的信號(hào)和槽

                QT的槽函數(shù)可以被聲明為虛函數(shù),所以雖然QT在實(shí)現(xiàn)信號(hào)和槽機(jī)制的時(shí)候可

            能出于效率或者運(yùn)行代價(jià)的原因未采用虛函數(shù)機(jī)制,但是我們依然可以在必要的

            時(shí)候使用虛函數(shù)來(lái)完成一些特定功能。比如為一些自定義控件類(lèi)抽象出來(lái)一個(gè)抽

            象接口基類(lèi),在做信號(hào)和槽的連接的時(shí)候是對(duì)基類(lèi)指針進(jìn)行操作,而在基類(lèi)里的

            槽定義為虛函數(shù),那么虛函數(shù)在此依然可以實(shí)現(xiàn)信號(hào)與槽的多態(tài)。

                然而虛函數(shù)在調(diào)用的時(shí)候,一定要經(jīng)歷查表的步驟,是存在一定的運(yùn)行開(kāi)銷(xiāo)

            的,對(duì)于一些非常頻繁的槽調(diào)用還是應(yīng)該考慮到使用虛函數(shù)產(chǎn)生的代價(jià)的。

                其他

                在虛函數(shù)上,static和inline這兩個(gè)關(guān)鍵詞與virtual顯得很不友好。

                從語(yǔ)義上即可看出,static和virtual完全就是沖突的,所以如果你試圖為一

            個(gè)虛函數(shù)增加一個(gè)static限定詞,那么你的C++編譯器就會(huì)很負(fù)責(zé)任的報(bào)告一個(gè)嚴(yán)

            重錯(cuò)誤給你。

                而inline的含義和虛函數(shù)其實(shí)也是非常沖突的,但是inline在語(yǔ)法上只是給

            編譯器一個(gè)建議,而不是強(qiáng)制的語(yǔ)義限定,所以C++編譯器應(yīng)該會(huì)忽略掉inline關(guān)

            鍵詞,繼續(xù)正常的編譯。

             

            posted on 2009-08-05 17:47 chaosuper 閱讀(302) 評(píng)論(0)  編輯 收藏 引用

            只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


            99久久精品国内| 久久热这里只有精品在线观看| 久久国产精品成人片免费| 97久久久精品综合88久久| www.久久热| 欧美久久久久久精选9999| 亚洲伊人久久综合中文成人网| 偷窥少妇久久久久久久久| 精品久久8x国产免费观看| 久久综合伊人77777| 久久人人爽人人爽人人AV东京热| 亚洲成人精品久久| 亚洲精品无码久久久影院相关影片| 久久久久免费精品国产| 免费无码国产欧美久久18| 国产成人久久精品二区三区| 麻豆AV一区二区三区久久| 青青草原综合久久大伊人导航| 国产精品99久久99久久久| 精品国产99久久久久久麻豆| 国产免费久久精品丫丫| 2021精品国产综合久久| 亚洲国产精品综合久久网络| 97久久精品午夜一区二区| 久久成人国产精品免费软件| 久久久久久国产精品免费免费| 国产精品美女久久久久网| 国产亚洲精品自在久久| 亚洲午夜久久久久妓女影院| 欧美精品国产综合久久| 伊人热热久久原色播放www| 香蕉久久AⅤ一区二区三区| 精品久久久久中文字| 91精品国产高清久久久久久91| 久久精品中文无码资源站| 少妇精品久久久一区二区三区| 国内高清久久久久久| 少妇精品久久久一区二区三区| 久久久久久亚洲AV无码专区| 色综合久久无码五十路人妻| 久久久精品人妻一区二区三区蜜桃|