有一些 C 的語法,在 C++ 的程序員相對少用。

但就是因為這個原因,有時就會忽略了。

 

假設我們有一個Header檔 Foo.h:

 

有一些 C 的語法,在 C++ 的程序員相對少用。但就是因為這個原因,有時就會忽略了。

假設我們有一個Header檔 Foo.h:

1
2
3
4
5
6
7
8
9
10
 
static void f1()
{
    std::cout << "f1()" << std::endl;
}
 
void f2()
{
    std::cout << "f2()" << std::endl;
}

f1 和 f2 的分別在於 static 這個 keyword 。

在這裡的 f1 被宣告和定義(declare)1為 static ,是指它只在這個Compilation Unit中生效。

而 f2 沒有被定義為 static ,亦即是它可以被其他 Compilation Unit 訪問。

但到底什麼是 Compilation Unit呢?? 首先,一個程式編譯過程如下:

1.gif 

這裡的 a.cpp , b.cpp 和 c.cpp 也 引入2了Foo.h 這個檔案,

經過預處理器3後,Foo.h的內容會被加入到 a.cpp, b.cpp 和 c.cpp 中,

再經過編譯器4,變成為 a.o , b.o 和 c.o 這些目的碼5,最後經過連結器6,變成執行檔7

要留意的地方是,每個經過預處理器處理後的.cpp 檔,和它的目的檔是一一對應的,而Compilation Unit,就是這些被處理後的.cpp 檔了。

若以Foo.h 的 f1 為例子,雖然在每個 .cpp 檔也被定義了,但經過編譯後,所有的f1 也會被隱藏在自己的目的檔中。

連結器在找尋symbol的過程中,是會忽略的。

但f2 就不同了,所有的f2 在目的檔中,也是不會被隱藏,所以在連結器找尋symbol,會找到多份的f2,那就會有連結器錯誤8了。

所以在大部份的情況下,在Header檔中定義函數9,也是需要static 這個keyword 的。就算加上了inline,情況也是一樣的。

1
2
3
4
static inline void f3()
{
  std::cout << "f3() is called" << std::endl;
}

  1. 宣告(declare)和定義(define)的分別,也是一個很好的課題
  2. include
  3. Preprocessor
  4. compiler
  5. Object files
  6. Linker
  7. Executable
  8. 或者是警告(warning)
  9. 這裡的是指Free Function,而不是Member Method

 

 

 

arrow
arrow
    全站熱搜

    BB 發表在 痞客邦 留言(0) 人氣()