• <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)注問題:

                虛函數(shù)的作用

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

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

                虛函數(shù)的類的sizeof

                純虛函數(shù)的作用

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

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

                多繼承時(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)到的各種資源的。最常見的,當(dāng)

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

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

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

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

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

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

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

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

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

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

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

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

            用子類的析構(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類型的對(duì)象,然后使用free_child

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

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

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

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

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

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

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

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

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

            數(shù)。

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

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

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

                QT的事件機(jī)制

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

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

                virtual bool event(QEvent *);

                virtual bool eventFilter(QObject *, QEvent *);

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

            多窗口控件類的缺省事件處理。

                當(dāng)你要編寫自定義的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ù)來完成一些特定功能。比如為一些自定義控件類抽象出來一個(gè)抽

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

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

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

            的,對(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è)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            久久国产成人亚洲精品影院| 欧美午夜精品久久久久免费视 | 久久精品www人人爽人人| 久久久久无码精品国产| 久久夜色精品国产亚洲| 亚洲美日韩Av中文字幕无码久久久妻妇| 欧美精品一区二区久久| 久久亚洲私人国产精品vA| 久久精品国产亚洲Aⅴ香蕉| 久久亚洲AV成人无码| 成人午夜精品久久久久久久小说 | 久久精品亚洲男人的天堂| 久久久精品国产免大香伊| 9191精品国产免费久久| 日韩精品久久久肉伦网站| 亚洲国产成人精品91久久久| 精品久久久久久中文字幕人妻最新| 久久AⅤ人妻少妇嫩草影院| 人妻精品久久久久中文字幕69| 国产精品成人精品久久久| AAA级久久久精品无码片| 久久久久久曰本AV免费免费| 久久艹国产| 国产精品gz久久久| 青青国产成人久久91网| 久久久久亚洲精品无码蜜桃| 国内精品久久久久久久久电影网 | 色青青草原桃花久久综合| 91久久精品国产免费直播| www性久久久com| 波多野结衣AV无码久久一区| 亚洲国产成人久久一区WWW| 久久无码一区二区三区少妇| 久久99精品久久久久久水蜜桃| 久久久久久综合一区中文字幕| 久久丫精品国产亚洲av不卡 | 尹人香蕉久久99天天拍| 久久伊人中文无码| 国产精品成人久久久| 亚洲日本久久久午夜精品| 狠狠精品久久久无码中文字幕|