c++標頭檔

來源:互聯網
上載者:User

標頭檔是c/c++中特有的概念。

首先解釋聲明和定義的區別。extern int x;此為變數x聲明,void fun();此為函數fun()聲明,class a;此為類a聲明。int x;為變數x定義,void fun(){};則為fun()函數的定義,class a{};則為類a的定義。

標頭檔中存放預先處理命令(#開頭的命令),函式宣告,類、結構體、聯合定義(不能執行個體化對象),模板定義等。而不應該包含變數定義,函數定義等。標頭檔中的內容不會去產生目標代碼,不會去為變數聲明或類定義分配記憶體空間,都只是一些聲明性的東西。#include在編譯的先行編譯階段展開用相應的標頭檔內容替換。

編譯單元是指一個cpp檔案,可以產生一個目標檔案。同一個編譯單元中可以有重複的聲明,但是不允許重複的變數定義、函數定義、類定義。不同的編譯單元可以有重複的聲明和類定義(這裡比較特殊,因為類定義只是聲明性的東西,沒有實際產生目標代碼,故可以放在不同的編譯單元中,而在同一編譯單元中不能重複定義),不允許重複的變數定義和函數定義。

為了防止在同一個編譯單元中標頭檔重複引用導致出現類重複定義等問題,在每個標頭檔定義時加入#ifndef  #define #endif的定義。並且該條件編譯指令也可以避免標頭檔的循引用,在程式先行編譯階段,碰到#include命令即展開對應的標頭檔,在展開那個標頭檔時同理處理。比如有三個標頭檔a.h b.h c.h,a.h裡面有#include "b.h",b.h裡面有#include "c.h", c.h裡面有#include "a.h",這就會造成檔案的循環相依性,此時若有個檔案a.c,其中#include "a.h",那在a.c檔案編譯之前,預先處理程式就會不斷的把這三個標頭檔的內容複寫過來,超過了一定的數量,就會導致“標頭檔數太多”的編譯錯誤。當使用#ifndef...#define...#endif條件編譯命令後,第一次展開a.h b.h c.h的時候就已經定義了宏,到了c.h中的#include "a.h"時候,遇到了#ifndef,由於這個宏在上一次展開時已經定義了,所以這部分就跳過去了。也就是每個標頭檔最多隻在每個源檔案裡麵包含一次。

下面解決一個實際問題即兩個類A,B中都有另一個類的指標,即彼此互相引用。這裡可以用前置聲明來解決。

標頭檔a.h

#ifndef A_H#define A_Hclass B;class A{public:B* b;};#endif

標頭檔b.h

#ifndef B_H#define B_Hclass A;class B{public:A* a;};#endif
使用標頭檔時的兩個原則:

1、如果可以不包含標頭檔,那就不要包含了。這時候前置聲明可以解決問題。如果使用的僅僅是一個類的指標,沒有使用這個類的具體對象(非指標),也沒有訪問到類的具體成員,那麼前置聲明就可以了。因為指標這一資料類型的大小是特定的,編譯器可以獲知。
2、盡量在CPP檔案中包含標頭檔,而非在標頭檔中。假設類A的一個成員是是一個指向類B的指標,在類A的標頭檔中使用了類B的前置聲明並 便宜成功,那麼在A的實現中我們需要訪問B的具體成員,因此需要包含標頭檔,那麼我們應該在類A的實現部分(CPP檔案)包含類B的標頭檔而非聲明部



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.