1. <ul id="0c1fb"></ul>

      <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
      <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区

      RELATEED CONSULTING
      相關(guān)咨詢
      選擇下列產(chǎn)品馬上在線溝通
      服務(wù)時(shí)間:8:30-17:00
      你可能遇到了下面的問(wèn)題
      關(guān)閉右側(cè)工具欄

      新聞中心

      這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
      減少C++代碼編譯時(shí)間的簡(jiǎn)單方法(必看篇)

      c++ 的代碼包含頭文件和實(shí)現(xiàn)文件兩部分, 頭文件一般是提供給別人(也叫客戶)使用的, 但是一旦頭文件發(fā)生改變,不管多小的變化,所有引用他的文件就必須重新編譯,編譯就要花時(shí)間,假如你做的工程比較大(比如二次封裝chrome這類(lèi)的開(kāi)發(fā)),重新編譯一次的時(shí)間就會(huì)浪費(fèi)上班的大部分時(shí)間,這樣干了一天挺累的, 但是你的老板說(shuō)你沒(méi)有產(chǎn)出,結(jié)果你被fired, 是不是很怨啊, 如果你早點(diǎn)看到這段文章,你就會(huì)比你的同事開(kāi)發(fā)效率高那么一些,那樣被fired就不會(huì)是你了,你說(shuō)這篇文章是不是價(jià)值千金!開(kāi)個(gè)玩笑 :)

      創(chuàng)新互聯(lián)公司網(wǎng)站建設(shè)公司一直秉承“誠(chéng)信做人,踏實(shí)做事”的原則,不欺瞞客戶,是我們最起碼的底線! 以服務(wù)為基礎(chǔ),以質(zhì)量求生存,以技術(shù)求發(fā)展,成交一個(gè)客戶多一個(gè)朋友!專(zhuān)注中小微企業(yè)官網(wǎng)定制,網(wǎng)站設(shè)計(jì)、網(wǎng)站建設(shè),塑造企業(yè)網(wǎng)絡(luò)形象打造互聯(lián)網(wǎng)企業(yè)效應(yīng)。

      言歸正傳,怎樣介紹編譯時(shí)間呢, 我知道的就3個(gè)辦法:

      1. 刪除不必要的#include,替代辦法 使用前向聲明 (forward declared )

      2. 刪除不必要的一大堆私有成員變量,轉(zhuǎn)而使用 "impl" 方法

      3. 刪除不必要的類(lèi)之間的繼承

      為了講清楚這3點(diǎn),還是舉個(gè)實(shí)例比較好,這個(gè)實(shí)例我會(huì)一步一步的改進(jìn)(因?yàn)槲乙彩且稽c(diǎn)一點(diǎn)摸索出來(lái)了,如果哪里說(shuō)錯(cuò)了, 你就放心的噴吧,我會(huì)和你在爭(zhēng)論到底的,呵呵)

      現(xiàn)在先假設(shè)你找到一個(gè)新工作,接手以前某個(gè)程序員寫(xiě)的類(lèi),如下

      // old.h: 這就是你接收的類(lèi)
         //
         #include 
         #include 
         #include 
       
         // 5 個(gè) 分別是file , db, cx, deduce or error , 水平有限沒(méi)有模板類(lèi)
         // 只用 file and cx 有虛函數(shù).
         #include "file.h" // class file
         #include "db.h" // class db
         #include "cx.h" // class cx
         #include "deduce.h" // class deduce
         #include "error.h" // class error
       
         class old : public file, private db {
         public:
           old( const cx& );
          db get_db( int, char* );
          cx get_cx( int, cx );
          cx& fun1( db );
          error fun2( error );
          virtual std::ostream& print( std::ostream& ) const;
         private:
          std::list cx_list_;
          deduce    deduce_d_;
         };
          inline std::ostream& operator<<( std::ostream& os,const old& old_val )
          { return old_val.print(os); }

      這個(gè)類(lèi)看完了, 如果你已經(jīng)看出了問(wèn)題出在哪里, 接下來(lái)的不用看了, 你是高手, 這些基本知識(shí)對(duì)你來(lái)說(shuō)太小兒科,要是像面試時(shí)被問(wèn)住了愣了一下,請(qǐng)接著看吧

      先看怎么使用第一條: 刪除不必要的#include

      這個(gè)類(lèi)引用 5個(gè)頭文件, 那意味著那5個(gè)頭文件所引用的頭文件也都被引用了進(jìn)來(lái), 實(shí)際上, 不需要引用5 個(gè),只要引用2個(gè)就完全可以了

      1.刪除不必要的#include,替代辦法 使用前向聲明 (forward declared )

      1.1刪除頭文件 iostream, 我剛開(kāi)始學(xué)習(xí)c++ 時(shí)照著《c++ primer》 抄,只要看見(jiàn)關(guān)于輸入,輸出就把 iostream 頭文件加上, 幾年過(guò)去了, 現(xiàn)在我知道不是這樣的, 這里只是定義輸出函數(shù), 只要引用ostream 就夠了

      1.2.ostream頭文件也不要, 替換為 iosfwd , 為什么, 原因就是, 參數(shù)和返回類(lèi)型只要前向聲明就可以編譯通過(guò), 在iosfwd 文件里 678行(我的環(huán)境是vs2013,不同的編譯環(huán)境具體位置可能會(huì)不相同,但是都有這句聲明) 有這么一句

      typedef basic_ostream > ostream;
      
      inline std::ostream& operator<<( std::ostream& os,const old& old_val )
      
      { return old_val.print(os); }
      

      除此之外,要是你說(shuō)這個(gè)函數(shù)要操作ostream 對(duì)象, 那還是需要#include , 你只說(shuō)對(duì)了一半, 的確, 這個(gè)函數(shù)要操作ostream 對(duì)象, 但是請(qǐng)看他的函數(shù)實(shí)現(xiàn),

      里面沒(méi)有定義一個(gè)類(lèi)似 std::ostream os, 這樣的語(yǔ)句,話說(shuō)回來(lái),但凡出現(xiàn)這樣的定義語(yǔ)句, 就必須#include 相應(yīng)的頭文件了 ,因?yàn)檫@是請(qǐng)求編譯器分配空間,而如果只前向聲明 class XXX; 編譯器怎么知道分配多大的空間給這個(gè)對(duì)象!

      看到這里, old.h頭文件可以更新如下了:

      // old.h: 這就是你接收的類(lèi)
         //
         #include  //新替換的頭文件
         #include 
       
         // 5 個(gè) 分別是file , db, cx, deduce or error , 水平有限沒(méi)有模板類(lèi)
         // 只用 file and cx 有虛函數(shù).
         #include "file.h" // class file , 作為基類(lèi)不能刪除,刪除了編譯器就不知道實(shí)例化old 對(duì)象時(shí)分配多大的空間了
         #include "db.h" // class db, 作為基類(lèi)不能刪除,同上
         #include "cx.h" // class cx
         #include "deduce.h" // class deduce
         // error 只被用做參數(shù)和返回值類(lèi)型, 用前向聲明替換#include "error.h" 
         class error;
       
         class old : public file, private db {
         public:
           old( const cx& );
          db get_db( int, char* );
          cx get_cx( int, cx );
          cx& fun1( db );
          error fun2( error );
          virtual std::ostream& print( std::ostream& ) const;
         private:
          std::list cx_list_; // cx 是模版類(lèi)型,既不是函數(shù)參數(shù)類(lèi)型也不是函數(shù)返回值類(lèi)型,所以cx.h 頭文件不能刪除
          deduce    deduce_d_; // deduce 是類(lèi)型定義,也不刪除他的頭文件
         };
          inline std::ostream& operator<<( std::ostream& os,const old& old_val )
          { return old_val.print(os); }

      到目前為止, 刪除了一些代碼, 是不是心情很爽,據(jù)說(shuō)看一個(gè)程序員的水平有多高, 不是看他寫(xiě)了多少代碼,而是看他少寫(xiě)了多少代碼。

      如果你對(duì)C++ 編程有更深一步的興趣, 接下來(lái)的文字你還是會(huì)看的,再進(jìn)一步刪除代碼, 但是這次要另辟蹊徑了

      2. 刪除不必要的一大堆私有成員變量,轉(zhuǎn)而使用 "impl" 方法

      2.1.使用 "impl" 實(shí)現(xiàn)方式寫(xiě)代碼,減少客戶端代碼的編譯依賴(lài)

      impl 方法簡(jiǎn)單點(diǎn)說(shuō)就是把 類(lèi)的私有成員變量全部放進(jìn)一個(gè)impl 類(lèi), 然后把這個(gè)類(lèi)的私有成員變量只保留一個(gè)impl* 指針,代碼如下

      // file old.h
         class old {
          //公有和保護(hù)成員
          // public and protected members
         private:
         //私有成員, 只要任意一個(gè)的頭文件發(fā)生變化或成員個(gè)數(shù)增加,減少,所有引用old.h的客戶端必須重新編譯
          // private members; whenever these change,
          // all client code must be recompiled
         };

      改寫(xiě)成這樣:

      // file old.h
         class old {
         //公有和保護(hù)成員
          // public and protected members
         private:
          class oldImpl* pimpl_;
          // 替換原來(lái)的所有私有成員變量為這個(gè)impl指針,指針只需要前向聲明就可以編譯通過(guò),這種寫(xiě)法將前向聲明和定義指針?lè)旁诹艘黄穑?完全可以。
          //當(dāng)然,也可以分開(kāi)寫(xiě)
           // a pointer to a forward-declared class
         };
       
         // file old.cpp
         struct oldImpl {
         //真正的成員變量隱藏在這里, 隨意變化, 客戶端的代碼都不需要重新編譯
          // private members; fully hidden, can be
          // changed at will without recompiling clients
         };
      

      不知道你看明白了沒(méi)有, 看不明白請(qǐng)隨便寫(xiě)個(gè)類(lèi)試驗(yàn)下,我就是這么做的,當(dāng)然凡事也都有優(yōu)缺點(diǎn),下面簡(jiǎn)單對(duì)比下:

      使用impl實(shí)現(xiàn)類(lèi)

      不使用impl實(shí)現(xiàn)類(lèi)

      優(yōu)點(diǎn)

      類(lèi)型定義與客戶端隔離, 減少#include的次數(shù),提高編譯速度,庫(kù)端的類(lèi)隨意修改,客戶端不需要重新編譯

      直接,簡(jiǎn)單明了,不需要考慮堆分配,釋放,內(nèi)存泄漏問(wèn)題

      缺點(diǎn)

      對(duì)于impl的指針必須使用堆分配,堆釋放,時(shí)間長(zhǎng)了會(huì)產(chǎn)生內(nèi)存碎片,最終影響程序運(yùn)行速度, 每次調(diào)用一個(gè)成員函數(shù)都要經(jīng)過(guò)impl->xxx()的一次轉(zhuǎn)發(fā)

      庫(kù)端任意頭文件發(fā)生變化,客戶端都必須重新編譯

      改為impl實(shí)現(xiàn)后是這樣的:

      // 只用 file and cx 有虛函數(shù).
         #include "file.h" 
         #include "db.h" 
         class cx;
         class error;
       
         class old : public file, private db {
         public:
           old( const cx& );
          db get_db( int, char* );
          cx get_cx( int, cx );
          cx& fun1( db );
          error fun2( error );
          virtual std::ostream& print( std::ostream& ) const;
         private:
      class oldimpl* pimpl; //此處前向聲明和定義
         };
          inline std::ostream& operator<<( std::ostream& os,const old& old_val )
          { return old_val.print(os); }
       
      //implementation file old.cpp
      class oldimpl{
      std::list cx_list_;
      deduce    dudece_d_;
      };

      3. 刪除不必要的類(lèi)之間的繼承

      面向?qū)ο筇峁┝死^承這種機(jī)制,但是繼承不要濫用, old class 的繼承就屬于濫用之一, class old 繼承file 和 db 類(lèi), 繼承file是公有繼承,繼承db 是私有繼承,繼承file 可以理解, 因?yàn)閒ile 中有虛函數(shù), old 要重新定義它, 但是根據(jù)我們的假設(shè), 只有file 和 cx 有虛函數(shù),私有繼承db 怎么解釋?zhuān)? 那么唯一可能的理由就是:

      通過(guò) 私有繼承—讓某個(gè)類(lèi)不能當(dāng)作基類(lèi)去派生其他類(lèi),類(lèi)似Java里final關(guān)鍵字的功能,但是從實(shí)例看,顯然沒(méi)有這個(gè)用意, 所以這個(gè)私有繼承完全不必要, 應(yīng)該改用包含的方式去使用db類(lèi)提供的功能, 這樣就可以

      把"db.h"頭文件刪除, 把db 的實(shí)例也可以放進(jìn)impl類(lèi)中,最終得到的類(lèi)是這樣的:

      // 只用 file and cx 有虛函數(shù).
         #include "file.h" 
         class cx;
         class error;
         class db;
         class old : public file {
         public:
           old( const cx& );
          db get_db( int, char* );
          cx  get_cx( int, cx );
          cx& fun1( db );
          error fun2( error );
          virtual std::ostream& print( std::ostream& ) const;
         private:
          class oldimpl* pimpl; //此處前向聲明和定義
         };
          inline std::ostream& operator<<( std::ostream& os,const old& old_val )
          { return old_val.print(os); }
       
      //implementation file old.cpp
      class oldimpl{
      std::list cx_list_;
      deduce    dudece_d_;
      };

      小結(jié)一下:

      這篇文章只是簡(jiǎn)單的介紹了減少編譯時(shí)間的幾個(gè)辦法:

      1. 刪除不必要的#include,替代辦法 使用前向聲明 (forward declared )

      2. 刪除不必要的一大堆私有成員變量,轉(zhuǎn)而使用 "impl" 方法

      3. 刪除不必要的類(lèi)之間的繼承

      這幾條希望對(duì)您有所幫助, 如果我哪里講的不夠清楚也可以參考附件,哪里有完整的實(shí)例,也歡迎您發(fā)表評(píng)論, 大家一起討論進(jìn)步,哦不,加薪。 呵呵,在下篇文章我將把impl實(shí)現(xiàn)方式再詳細(xì)分析下,期待吧...

      以上就是小編為大家?guī)?lái)的減少C++代碼編譯時(shí)間的簡(jiǎn)單方法(必看篇)全部?jī)?nèi)容了,希望大家多多支持創(chuàng)新互聯(lián)~


      網(wǎng)頁(yè)題目:減少C++代碼編譯時(shí)間的簡(jiǎn)單方法(必看篇)
      網(wǎng)頁(yè)地址:http://www.ef60e0e.cn/article/gpjooh.html
      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区
      1. <ul id="0c1fb"></ul>

        <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
        <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

        蒙山县| 青州市| 虹口区| 咸宁市| 缙云县| 伊宁市| 乐陵市| 浑源县| 濉溪县| 南充市| 宁海县| 滨海县| 长阳| 兴和县| 南涧| 西吉县| 吉首市| 柯坪县| 台安县| 衡水市| 乌鲁木齐市| 福清市| 芦溪县| 伊春市| 裕民县| 通榆县| 崇文区| 铅山县| 疏附县| 开化县| 信丰县| 独山县| 会宁县| 伊春市| 宣恩县| 葵青区| 长宁县| 乐清市| 铅山县| 娄底市| 泸西县|