基礎語法之二:頭文件與源文件

一、頭文件和源文件應該寫什麼

    首先頭文件和源文件應該寫什麼,這需要先理解C++的編譯機制,C++語言以"xxx.cpp"爲單位進行編譯生成 xxx.obj,然後目標文件鏈接生成 xxx.exe (windows 上),也即xxx.h文件是不參與編譯,那麼頭文件如何起到作用呢,這就要說起 #include宏,通過該宏命令,源文件將頭文件的內容複製到源文件,就如同寫在源文件是一樣。這也就不難理解,爲什麼說定義頭文件可以是代碼重用了 ^_^。 OK,到目前還是沒有說頭文件和源文件應該寫什麼,尷尬! 接着代碼重用來說,如果在頭文件定義了一個變量或這函數並且頭文件被重用(多處包含),此時編譯就會報出“重定義”!因此依據話,C++頭文件寫變量和函數的聲明,注意是聲明!!!而不能是定義(例外見下一節)。源文件中寫變量和函數的定義,當然也可以在源文件中同時寫聲明和定義(這樣的變量或者函數用來做源文件私有,或者在其他文件使用時使用extern聲明一下,然後使用)。

舉個栗子:

  

1

2

3

4

5

6

7

8

9

10

11

12

13

// test.h

 

#ifndef _TEST_H_

#define _TEST_H_

 

#include<string>

 

using namespace std;

 

string str;

extern void show();

 

#endif

 

1

2

3

4

5

6

7

8

9

10

11

// test.cpp

 

#include "test.h"

#include<iostream>

#include<string>

 

str = "Hi, I'm test!"

void show()

{

    cout<< str << endl;

}

  

二、符號重定義和例外情況

  1. static變量 :static變量具有內鏈接屬性,所以對外不文件不可見,不會產生命名衝突。值得一提 const 變量有時也會在頭文件中定義,這是因爲編譯器默認 const 變量是內鏈接的,所以可以在頭文件定義,但如果是用 extern const修飾,在頭文件中則只能聲明不能定義。還有一種常見的修飾組合 static const 常用來修飾文件內的常值。
  2. inline函數:inline函數默認也是內鏈接屬性的,所以不會產生函數重定義,當然使用extern inline組合修飾,就不能放在頭文件了。
  3. 類定義:爲什麼頭文件可以定義類,而不會產生重命名,因爲類定義默認是內連接的,其實類定義是一種聲明,聲明瞭一種數據結構類型。

根本來講,之所以存在鏈接屬性、以及上面三種例外,遵頊基本的原則:   "在頭文件中定義這些實體,是因爲編譯器需要它們的定義(不只是聲明)來產生代碼"。

 

三、符號重定義解決辦法

1、使宏變量標識(c++的語法)

1

2

3

4

5

6

#ifndf _XXX_H_

#define _XXX_H_

 

//content

 

#endif

  缺點:本方法可能會產生宏名稱"撞車",從而產生漏包含一些頭文件定義內容,最終產生缺少定義錯誤!

2、使用 #program once(編譯器支持)

 缺點:本方法是針對文件物理上的只編譯一次,如果兩個不同命的文件,保存了相同內容並且均包含在項目中,則會出現重定義錯誤。不過比起1,這個錯誤更易排查,所以使用更廣。 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章