亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

C++文件依存關(guān)系介紹

 更新時(shí)間:2013年01月02日 17:22:18   作者:  
如果現(xiàn)在你做的C++項(xiàng)目(課題)包含的文件沒有超過1000個(gè),你可以選擇略過此文,不過建議繼續(xù)瀏覽

如果你覺得重新編譯文件的時(shí)間很短或者時(shí)間長一點(diǎn)無所謂,反正需要重新編譯,那么你也可以選擇略過此文,不過也建議瀏覽。
如果你想學(xué)習(xí)或者關(guān)心這塊內(nèi)容,那么此文必定會(huì)給你帶來收獲。
首先我不給出依存關(guān)系的定義,我給出一個(gè)例子。

復(fù)制代碼 代碼如下:

 class Peopel{
 public:
     People(const std::string & name,const Date& brithday,Image Img)
     std::string name( ) const;
     Date birthDate( ) const;
     Image img( ) const;
     ...
 private:
     std::string theName;               //名字
     Date theBirthDate;                 //生日
     Image img;                         //圖片
 };

如果編譯器沒有知道類string,Date和Image的定義,class People是無法通過編譯的。一般該定義式是由#include包含的頭文件所提供的,所以一般People上面有這些預(yù)處理命令
復(fù)制代碼 代碼如下:

  #include <string>
  #include "date.h"
  #inblude "image.h"
 class Peopel{
 public:
     People(const std::string & name,const Date& brithday,Image Img)
     std::string name( ) const;
     Date birthDate( ) const;
     Image img( ) const;
     ...
 private:
     std::string theName;               //名字
     Date theBirthDate;                 //生日
     Image img;                         //圖片
 };

那么這樣People定義文件與該三個(gè)文件之間就形成了一種編譯依存關(guān)系。如果這些頭文件任何一個(gè)文件被改變,或這些頭文件所依賴其他頭文件任何改變,那么每一個(gè)包含People類的文件就需要重新編譯,使用People類文件也需要重新編譯。想想如果一個(gè)項(xiàng)目包含一個(gè)上千的文件,每個(gè)文件包含其他幾個(gè)文件,依次這樣下來,改動(dòng)一個(gè)文件內(nèi)容,那么就需要幾乎重新編譯整個(gè)項(xiàng)目了,這可以說很槽糕了。

我們可以進(jìn)行如下改動(dòng)

復(fù)制代碼 代碼如下:

 namespace std {
     class string;
 }
 class Date;
 class Image;

 class Peopel{
 public:
     People(const std::string & name,const Date& brithday,Image& Img)
    std::string name( ) const;
    Date birthDate( ) const;
    Image img( ) const;
    ...
private:
    std::string theName;                //名字
    Date theBirthDate;                 //生日
    Image img;                         //圖片
};

這樣只有People該接口被改變時(shí)才會(huì)重新編譯,但是這樣有連個(gè)問題,第一點(diǎn)string不是class,它是個(gè)typedef basic_string<char> string。因此上述前置聲明不正確(附其在stl完全代碼);,正確的前置聲明比較復(fù)雜。其實(shí)對于標(biāo)準(zhǔn)庫部分,我們僅僅通過#include預(yù)處理命令包括進(jìn)來就可以了。
復(fù)制代碼 代碼如下:

 #ifndef __STRING__
 #define __STRING__

 #include <std/bastring.h>

 extern "C++" {
 typedef basic_string <char> string;
 // typedef basic_string <wchar_t> wstring;
 } // extern "C++"

#endif


前置聲明還有一個(gè)問題,就是編譯器必須在編譯期間知道對象的大小,以便分配空間。
例如:
復(fù)制代碼 代碼如下:

  int main(int argv,char * argc[ ])
    {
        int x;
        People p( 參數(shù) );
        ...
    }

當(dāng)編譯器看到x的定義式,它知道必須分配多少內(nèi)存,但是看到p定義式就無法知道了。但是如果設(shè)置為指針的話,就清楚了,因?yàn)橹羔槺旧泶笮【幾g器是知道的。
復(fù)制代碼 代碼如下:

#include <string>
#include <memory>

class PeopleImpl;
class Date;
class Image;
class People{
public:
   People(const std::string & name, const Date& brithday, const Image &Img);
   std::string name( ) const;
   Date birthDate( ) const;
   Imge img( ) const;
   ...
private:
   PeopleImpl * pImpl;
}


PeopleImpl包含下面這三個(gè)數(shù)據(jù),而People的成員變量指針指向這個(gè)PeopleImpl,那么現(xiàn)在編譯器通過People定義就知道了其分配空間的大小了,一個(gè)指針的大小。
復(fù)制代碼 代碼如下:

 public PeopleImpl
 {
     public:
         PeopleImple(...)
         ...
     private:
         std::string theName;                //名字
         Date theBirthDate;                 //生日
         Image img;                         //圖片


這樣,People就完全與Date、Imge以及People的實(shí)現(xiàn)分離了上面那些類任何修改都不需要重新編譯People文件了。另外這樣寫加強(qiáng)了封裝。這樣也就降低了文件的依存關(guān)系。
這里總結(jié)下降低依存性方法:

1.如果可以類聲明就不要使用類定義了。
2.將數(shù)據(jù)通過一個(gè)指向該數(shù)據(jù)的指針表示。
3.為聲明式和定義式提供不同的頭文件。
  這兩個(gè)文件必須保持一致性,如果有個(gè)聲明式被改變了,兩個(gè)文件都得改變。因此一般會(huì)有一個(gè)#include一個(gè)聲明文件而不是前置聲明若干函數(shù)。
  像People這樣定 

復(fù)制代碼 代碼如下:

 #include "People.h"
 #include "PeopleImpl.h"

 People::People(const std::string& name, const Date& brithday, const Image& Img)
 :pImpl(new PersonImpl(name,brithday,addr))
 { }
 std::string People::name( ) const
 {
     return pImpl->name( );
 }

而另外一種Handle類寫法是令People成為一種特殊的abstract base class稱為Interface類??吹絠nterface這個(gè)關(guān)鍵字或許熟悉C#、java的同學(xué)可能已經(jīng)恍然大悟了。這種接口它不帶成員變量,也沒有構(gòu)造函數(shù),只有一個(gè)virtual析構(gòu)函數(shù),以及一組純虛函數(shù),用來表示整個(gè)接口。針對People而寫的interface class看起來是這樣的。
復(fù)制代碼 代碼如下:

 class People{
 public:
     virtual ~People( );
     virtual std::string name( ) const = 0;
     virtual Date brithDate( ) const =0;
     virtual Image address( ) const =0;
     ...
 };

怎么創(chuàng)建對象呢?它們通常調(diào)用一個(gè)特殊函數(shù)。這樣的函數(shù)通常稱為工廠函數(shù)或者虛構(gòu)造函數(shù)。它們返回指針指向動(dòng)態(tài)分配所得對象,而該對象支持interface類的接口。
復(fù)制代碼 代碼如下:

   class People {
     public:
         ...
         static People* create(const std::string& name,const Date& brithday, const Image& Img);
     };

支持interface類接口的那個(gè)類必須定義出來,而且真正的構(gòu)造函數(shù)必須被調(diào)用
復(fù)制代碼 代碼如下:

 class RealPeople:public People{
 public:
     RealPeople(const std::string& name,const Date& birthday,const Image& Img)
     :theName(name),theBrithDate(brithday),theImg(Img)
 {}
     virtual ~RealPeople() { }
     std::string name( ) const;
     Date birthDate( ) const;
     Image img( ) const;
 private:
     std::string theName;
     Date theBirthDate;
     Image theImg;
 }

有了RealPeople類,我們People::create可以這樣寫
復(fù)制代碼 代碼如下:

 People* People::create(const std::string& name, const Date& birthday, const Image& Img)
 {
     return static_cast<People *>(new RealPerson(name,birthday,Img));
 }

Handle類與interface類解除了接口和實(shí)現(xiàn)之間的耦合關(guān)系,從而降低了文件間的編譯依存性。但同時(shí)也損耗了一些性能與空間。

相關(guān)文章

  • C++中的Lambda表達(dá)式詳解

    C++中的Lambda表達(dá)式詳解

    這篇文章主要介紹了C++中的Lambda表達(dá)式詳解,本文講解了基本語法、Lambda的使用等內(nèi)容,需要的朋友可以參考下
    2014-10-10
  • C語言版三子棋游戲

    C語言版三子棋游戲

    這篇文章主要為大家詳細(xì)介紹了C語言版三子棋游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • 關(guān)于C++的重載運(yùn)算符和重載函數(shù)

    關(guān)于C++的重載運(yùn)算符和重載函數(shù)

    一般來說,重載運(yùn)算符在實(shí)際的項(xiàng)目開發(fā)中會(huì)經(jīng)常的用到,但如果某些自定義類型通過簡短幾行代碼重載一些常用的運(yùn)算符(如:+-*/),就能讓編程工作帶來方便,需要的朋友可以參考下本文
    2023-05-05
  • C/C++深入講解內(nèi)存管理

    C/C++深入講解內(nèi)存管理

    本章主要介紹C語言與C++的內(nèi)存管理,以C++的內(nèi)存分布作為引入,介紹C++不同于C語言的內(nèi)存管理方式(new?delete對比?malloc?free),感興趣的朋友來看看吧
    2022-05-05
  • C++實(shí)現(xiàn)合并兩個(gè)排序的鏈表

    C++實(shí)現(xiàn)合并兩個(gè)排序的鏈表

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)合并兩個(gè)排序的鏈表,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-03-03
  • 圖解AVL樹數(shù)據(jù)結(jié)構(gòu)輸入與輸出及實(shí)現(xiàn)示例

    圖解AVL樹數(shù)據(jù)結(jié)構(gòu)輸入與輸出及實(shí)現(xiàn)示例

    這篇文章主要為大家介紹了C++圖解AVL樹數(shù)據(jù)結(jié)構(gòu)輸入與輸出操作示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • C++ list的實(shí)例詳解

    C++ list的實(shí)例詳解

    這篇文章主要介紹了 C++ list的實(shí)例詳解的相關(guān)資料,希望通過本文大家能夠理解掌握這部分內(nèi)容,需要的朋友可以參考下
    2017-09-09
  • C語言中回調(diào)函數(shù)和qsort函數(shù)的用法詳解

    C語言中回調(diào)函數(shù)和qsort函數(shù)的用法詳解

    這篇文章主要為大家詳細(xì)介紹一下C語言中回調(diào)函數(shù)和qsort函數(shù)的用法教程,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)C語言有一定幫助,需要的可以參考一下
    2022-07-07
  • c++中的4種類型轉(zhuǎn)化方式詳細(xì)解析

    c++中的4種類型轉(zhuǎn)化方式詳細(xì)解析

    const_cast該函數(shù)用于去除指針變量的常量屬性,將它轉(zhuǎn)換為一個(gè)對應(yīng)指針類型的普通變量。反過來,也可以將一個(gè)非常量的指針變量轉(zhuǎn)換為一個(gè)常指針變量
    2013-10-10
  • opencv3/C++ 實(shí)現(xiàn)SURF特征檢測

    opencv3/C++ 實(shí)現(xiàn)SURF特征檢測

    今天小編就為大家分享一篇opencv3/C++ 實(shí)現(xiàn)SURF特征檢測,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-12-12

最新評論