Keyword Static (Function) [C++ 求生筆記]

Keyword Static (Function) [C++ 求生筆記]

April 7, 2008 – 12:15 pm

有一些 C 的語法,在 C++ 的程序員相對少用。但就是因為這個原因,有時就會忽略了。
假設我們有一個Header檔 Foo.h:

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呢?? 首先,一個程式編譯過程如下:

compliation process

這裡的 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,情況也是一樣的

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 

  1. 5 Responses to “Keyword Static (Function) [C++ 求生筆記]”

  2. 但是想不到甚麼實際情況下才會把 static function 定義在 header file 裡。如果定義的內容是一樣的話,不就會有重複的執行碼嗎?

    只想到如果那 function 內引用了 macro(s),而那些 macro(s) 在不同的 compilation unit 裡有不同的定義。

    我覺得常見的錯誤反而是忘記在 cpp 裡的 free function 加上 static。


  3. 我就是看到公司的代碼有這樣的錯誤才寫下:

  4. class TSystem; // This class is a singleton class

  5. TSystem* System(){

  6. return TSystem::GetInstance();

  7. }

  8. 現在的 C++ 已經鼓勵用 unnamed namespace 代替 static 修飾 free function 以及 global (lifetime) instance.

  9. 原因有三:
    1. static 一個 keyword 同時俱備過多功能.
    2. static 的 free function 以及 instance 是 internal linkage. 不能拿來當作 template parameter.
    3. unnamed namespace 不但可用在 static 的 free function 以及 instance 上, 也可用在 class/struct 上. 是一個統一的作法.


  10. 對呀,我也開始使用 unnamed namespace 了,這一文其實重點是說 internal linkage,我想若連static 的internal linkage 方面不大清楚,那麼也不必談 unnamed namespace 吧,所以在這裡就沒有說了 :)


  11. 很努力的教育下一代阿. 越來越多人忽略了這些基礎知識, 盼 C++ 求生筆記可幫上一把.



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值