亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C++ > 正文

深入分析C++中聲明與定義的區別

2020-01-26 15:21:36
字體:
來源:轉載
供稿:網友

        首先談下聲明與定義的區別。
        聲明是將一個名稱引入程序。定義提供了一個實體在程序中的唯一描述。聲明和定義有時是同時存在的。

   如int a;   extern int b=1;

    只有當extern中不存在初始化式是才是聲明。其他情況既是定義也是聲明。

     但是在下列情況下,聲明僅僅是聲明:

    1:僅僅提供函數原型。如void func(int,int);    2: extern int a;    3:class A;    4:typedef聲明    5:在類中定義的靜態數據成員的聲明

   如:

class A {   public:   static int a;//聲明。 };

   下列情況下 ,定義僅僅是定義:

   1:在類定義之外,定義并初始化一個靜態數據成員。如 A::a=0;   2:在類外定義非內聯成員函數。
     聲明僅僅是將一個符號引入到一個作用域。而定義提供了一個實體在程序中的唯一描述。在一個給定的定義域中重復聲明一個符號是可以的,但是卻不能重復定義,否則將會引起編譯錯誤。但是在類中的成員函數和靜態數據成員卻是例外,雖然在類內它們都是聲明,但是也不能有多個。

如:

        明白了聲明與定義的區別,還需要明白 內部鏈接、外部鏈接。只有明白了它們你才會知道開頭提出的問題。

       在編譯時,編譯器只檢測程序語法和函數、變量是否被聲明。如果函數未被聲明,編譯器會給出一個警告,但可以生成目標文件。而在鏈接程序時,鏈接器會在所有的目標文件中找尋函數的實現。如果找不到,那到就會報鏈接錯誤碼(Linker Error)。在VC下,這種錯誤一般是:Link 2001錯誤,意思說是說,鏈接器未能找到函數的實現。

      鏈接把不同編譯單元產生的符號聯系起來。有兩種鏈接方式:內部鏈接和外部鏈接。

      如果一個符號名對于它的編譯單元來說是局部的,并且在鏈接時不可能與其他編譯單元中的同樣的名稱相沖突,那個這個符號就是內部鏈接。內部鏈接意味著對此符號的訪問僅限于當前的編譯單元中,對其他編譯單元都是不可見的。

       static關鍵字作用在全局變量時,表示靜態全局變量。但是作用域僅僅在當前文件作用域內。其他文件中即使使用extern聲明也是無法使用的。const也類似。

       帶有static、const關鍵字和枚舉類型的連接是內部的。

       具有內部鏈接的符號無法作用于當前文件外部,要讓其影響程序的其他部分,可以將其放在.h文件中。此時在所有包含此.h文件的源文件都有自己的定義且互不影響。

       類的定義具有內部鏈接,由于它是定義,因此在同一編譯單元中不能重復出現。如果需要在其他編譯單元使用,類必須被定義在頭文件且被其他文件包含。僅僅在其他文件中使用class a;聲明是不行的,原因就是類的定義是內部鏈接,不會在目標文件導出符號。也就不會被其他單元解析它們的未定義符號。理解這一點很重要。

     內聯函數也具有內部鏈接。

      在一個多文件的程序中,如果一個符號在鏈接時可以和其他編譯單元交互,那么這個名稱就有外部鏈接。外部鏈接意味著該定義不僅僅局限在單個編譯單元中。它可以在.o文件中產生外部符號??梢员黄渌幾g單元訪問用來解析它們未定義的符號。因此它們在整個程序中必須是唯一的,否則將會導致重復定義。

       非內聯成員函數、非內聯函數、非靜態自由函數都具有外部鏈接。

       內聯函數之所有具有內部鏈接,因為編譯器在可能的時候,會將所有 對函數的調用替換為函數體,不將任何符號寫入.o文件。

       判斷一個符號是內部鏈接還是外部鏈接的一個很好的方法就是看該符號是否被寫入.o文件。

       前面說的是定義對鏈接方式的影響,接下來說下聲明對鏈接方式的影響。

       由于聲明只對當前編譯單元有用,因此聲明并不將任何東西寫入.o文件。

       如extern int a;

       int func();

       這些聲明本身不會影響到.o文件的內容。每一個都只是命名一個外部符號,使當前的編譯單元在需要的時候可以訪問相應的全局定義。

     函數調用會導致一個未定義的符號被寫入到.o文件。如果a在該文件中沒有被使用,那么沒有被寫入到.o文件。而func函數有對此函數的調用。也就會將此符號寫入目標文件。此后此.o文件與定義此符號的.o文件被連接在一起,前面未定義的符號被解析。

     上述聲明有可能導致該符號被寫入目標文件中。但是以下聲明并不會導致該符號寫入到目標文件中。

如:

typedef int Int;Class A; struct s; union point; 

 
     它們的鏈接也是內部的。

     類聲明和類定義都是內部鏈接。只是為當前編譯單元所用。

     靜態的類數據成員的定義具有外部鏈接。如

class A {   static int a;//聲明。具有內部鏈接。 };

      靜態數據成員a僅僅是一個聲明,但是它的定義A::a=0;卻具有外部鏈接。

     C++對類和枚舉類型的處理方式是不一樣的。比如:在不定義類時可以聲明一個類。但是不能未經定義就聲明一個枚舉類型。

     基于以上的分析,我們可以知道:將具有外部鏈接的定義放在頭文件中幾乎都是編程錯誤。因為如果該頭文件中被多個源文件包含,那么就會存在多個定義,鏈接時就會出錯。

     在頭文件中放置內部鏈接的定義卻是合法的,但不推薦使用的。因為頭文件被包含到多個源文件中時,不僅僅會污染全局命名空間,而且會在每個編譯單元中有自己的實體存在。大量消耗內存空間,還會影響機器性能。

     const和static修飾的全局變量僅僅在當前文件作用域內有效。它們具有內部鏈接屬性。

    下面列出一些應該或是不應該寫入頭文件的定義:

//test.h #ifndef TEST_H #define TEST_H   int a;   //a有外部鏈接,不能在頭文件中定義。   extern int b=10;//同上。   const int c=2;//c具有內部鏈接,可以定在頭文件中但應該避免。   static int d=3;//同上。   static void func(){} //同上。   void func2(){} //同a。   void func3();//可以。僅僅是聲明。并不會導致符號名被寫入目標文件。 class A {   public:    static int e;//可以,具有內部鏈接。    int f;//可以,同上。    void func4();//聲明,內部鏈接。同上。 };   A::e=10;//不可以在頭文件中包含具有外部鏈接的定義。符號名別寫入目標文件。   void A:func4()//不可以,類成員函數。外部連接。 {  //,...... } #endif 

      相信大家現在明白為什么只在類型聲明成員函數,而不實現它是合法的了。也可以回答為什么類的定義可以放在.h文件中。而類的實現可以放在同名的cpp文件中。老師以前的介紹是說編譯器會自動尋找同名的cpp文件。其實是因為由于cpp文件中存儲的是成員函數的實現,而成員函數具有外部鏈接特性,會在目標文件產生符號。在此文件中此符號是定義過的。其他調用此成員函數的目標文件也會產生一個未定的符號。兩目標文件連接后此符號就被解析。注意static數據成員應該放在cpp文件中。而不能放在.h文件。

      有內部鏈接的定義可以定義在cpp文件中,并不會影響全局的符號空間 。但是在cpp文件作用域中要避免定義(并不禁止)沒有聲明為靜態的數據和函數,因為它們具有外部鏈接。

 int a; void func() {      ...... } 

      上述定義具有外部鏈接可能會與全局命名空間的其他符號名稱存在潛在沖突。如果確實需要使用全局的變量或函數。可以為它們加上static關鍵字。使其作用域局限在當前文件內,具有內部鏈接也就不會對全局命名空間產生影響。因為內聯函數和靜態自由函數、枚舉以及const類型的數據都具有內部鏈接,所以它們可以定義在cpp文件中,而不會影響全局命名空間。

      typedef和宏定義不會將符號引入.o文件,它們也可以出現在cpp文件中,不會影響全局命名空間。

      typedef 為一個已存在的類型創建一個別名。而不是創建一個新的類型。它不提供類型安全。如

typedef int IntA; typedef int InB;   

       在需要IntA的地方使用IntB是不會報錯的。它們可以互相替換。因為此我們稱它不提供類型安全。但是在定義函數類型時typedef經常使用,可以使定義更清晰。

      標準c庫提供一個assert宏,用以保證給定的表達式值非零。否則便會輸出錯誤信息并終止程序執行。只有在程序中沒有定義NDEBUG時,assert才會工作。一旦定義NDEBUG  ,assert語句將會被忽略 。注意與VC中的ASSERT相區別。ASSERT是vc提供的。當_DEBUG被定義時才會起作用。

在vc的DEBUG模式下_DEBUG會被定義。而在RELEASE模式下NDEBUG會被定義。

    好了,相信大家都會明白開頭提出的問題了。如果有不明白的,請務必留言哦。如有錯誤,也請不吝指正!!

    以上內容參考自《Large Scale C++ software design》。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩在线高清视频| 国产精品久久久久久久久久久久久| 国产精品免费网站| 国产欧美日韩亚洲精品| www.欧美精品一二三区| 国产丝袜一区二区三区| 亚洲色图18p| 亚洲一区精品电影| 亚洲二区在线播放视频| 97国产精品视频人人做人人爱| 欧美孕妇孕交黑巨大网站| 国产精品成人一区| 国产精品1区2区在线观看| 精品国产欧美成人夜夜嗨| 日韩综合视频在线观看| 色中色综合影院手机版在线观看| 国产精品一区二区3区| 国产丝袜高跟一区| 国产色综合天天综合网| 久久久精品电影| 欧美精品videossex性护士| 高清一区二区三区日本久| 国产日本欧美在线观看| 国产精品精品一区二区三区午夜版| 国内精品小视频在线观看| 91精品视频大全| 亚洲福利视频网| 久久精品视频99| 国产精品久久一区主播| 久久精品国产清自在天天线| 欧美性生交大片免网| 久久久亚洲天堂| 91国产精品视频在线| 韩日欧美一区二区| 成人免费网站在线看| 亚洲缚视频在线观看| 亚洲老板91色精品久久| 在线日韩欧美视频| 亚洲综合在线播放| 日韩在线中文字| 日韩在线中文字幕| 国产成人精品视频在线| 精品福利在线观看| 国产中文欧美精品| 久久久精品影院| 国产成人精品亚洲精品| 91久久在线播放| 日韩亚洲第一页| 成人两性免费视频| 91精品国产91久久久久久吃药| 欧美高清激情视频| 91在线播放国产| 精品日韩中文字幕| 久久69精品久久久久久久电影好| 成人女保姆的销魂服务| 欧美激情综合色综合啪啪五月| 日韩经典一区二区三区| 欧美国产高跟鞋裸体秀xxxhd| 中文字幕亚洲二区| 欧美一区二区视频97| 久久精品国产精品亚洲| 欧美大学生性色视频| 欧美日韩精品在线观看| 亚洲精品一区二区在线| 欧美激情一区二区三区在线视频观看| 国产91久久婷婷一区二区| 国产视频在线观看一区二区| 日韩精品福利网站| 国产精品嫩草影院一区二区| 国产999在线| 欧美性极品xxxx娇小| 国产精品视频一区国模私拍| 日韩av大片在线| 久久精品一偷一偷国产| 久久这里只有精品视频首页| 亚洲国产精品国自产拍av秋霞| 久久久久久久国产精品| 亚洲欧美色图片| 亚洲黄色片网站| 亚洲国产成人精品女人久久久| 亚洲电影天堂av| 欧美成人免费在线视频| 精品国产欧美成人夜夜嗨| 欧美亚洲成人免费| 亚洲国产一区自拍| 91精品免费看| 久久久999精品视频| 精品国产老师黑色丝袜高跟鞋| 91精品国产九九九久久久亚洲| 亚洲国产日韩欧美在线图片| 亚洲性夜色噜噜噜7777| 欧美午夜精品久久久久久久| 亚洲福利影片在线| 亚洲日韩中文字幕在线播放| 亚洲欧美国产精品va在线观看| 91高清在线免费观看| 日韩欧美在线免费| 久久精品久久久久久国产 免费| 国产女人18毛片水18精品| 久久精品视频一| 欧美日韩高清在线观看| 国产欧美韩国高清| xxxx欧美18另类的高清| 一区二区亚洲欧洲国产日韩| 成人av在线亚洲| 免费99精品国产自在在线| 欧美中文字幕在线播放| 亚洲国产成人在线播放| 韩剧1988在线观看免费完整版| 精品少妇v888av| 亚洲午夜国产成人av电影男同| 欧美裸身视频免费观看| 青青青国产精品一区二区| 国产噜噜噜噜久久久久久久久| 日韩av免费一区| 成人在线小视频| 色综合色综合网色综合| 日韩免费精品视频| 中文字幕亚洲无线码a| 欧美最顶级的aⅴ艳星| 在线色欧美三级视频| 国产v综合ⅴ日韩v欧美大片| 最新国产精品拍自在线播放| 久久免费成人精品视频| 欧美精品在线观看| 欧美成年人视频网站欧美| 中文字幕av一区二区三区谷原希美| 成人午夜高潮视频| 中文字幕日韩免费视频| 九九热精品视频在线播放| 国产综合色香蕉精品| 日本成人在线视频网址| 青青久久av北条麻妃海外网| 亚洲精品资源在线| 久久久在线免费观看| 国产日韩欧美视频在线| 国产视频精品va久久久久久| 在线成人激情黄色| 精品一区二区三区四区在线| 91av在线看| 亚洲精品国产精品国自产观看浪潮| 色系列之999| 欧美综合一区第一页| 伊人久久大香线蕉av一区二区| 色樱桃影院亚洲精品影院| 亚洲国产欧美日韩精品| 久久99国产精品久久久久久久久| 精品国产91乱高清在线观看| 亚洲性av在线| 日韩精品中文字幕有码专区| 欧美精品激情视频| 国产精品尤物福利片在线观看| 亚洲综合最新在线| 欧美一级成年大片在线观看| 91精品综合久久久久久五月天| 日韩av成人在线观看| 欧美日韩精品在线观看| 国产成人精品a视频一区www| 久久亚洲国产精品成人av秋霞| 亚洲精品suv精品一区二区| 97人人模人人爽人人喊中文字| 欧美孕妇与黑人孕交| 久久天天躁狠狠躁夜夜爽蜜月| 亚洲精品xxx|