2010-12-06 111 views
4

我剛開始學習C++。有人可以解釋下面的C++函數原型之間的區別嗎?C++函數原型

void f(int n); 
extern void f(int n); 
static void f(int n); 

回答

11

void和extern void版本相同。它們表明函數具有外部鏈接(即函數的定義可能來自其他C或C++文件)。 Static表示該函數具有內部鏈接,並且僅存在於當前C++文件中。

您幾乎從來沒有看到這些說明符適用於函數,因爲99.9%的時間需要默認的extern行爲。

您可能會在全局變量上看到staticextern存儲說明符,這通常是爲了減少與同一項目中其他文件的名稱衝突。這是C的延期;如果你使用C++,這種事情應該使用匿名命名空間而不是static來完成。

+4

輕微nitpick:第一個不*必然*表示外部鏈接。它可以簡單地作爲函數定義的前向聲明,稍後將出現在同一個翻譯單元中。 – 2010-12-06 19:23:18

+0

@Charles:如果函數存在於同一個實現文件中,那麼它將被同一文件導出供其他文件使用,在這種情況下,它仍然具有外部鏈接。 (雖然你認爲這個函數本身不需要來自另一個翻譯單元) – 2010-12-06 19:24:56

3

前兩個是一樣的東西。第三個給出f內部鏈接,這意味着一個不同的源文件可能使用名稱f是不同的。

不應使用static與第三個示例中的一樣。相反,使用匿名命名空間:

namespace { // anonymous 
    void f(int n); 
} 
4

這比C++的一個C語言問題,而是:

void f(int n); 

聲明一個函數f接受單個整型參數。

extern void f(int n); 

聲明一個函數f,該函數只接受一個整數參數,但存在於其他文件中。編譯器會相信你已經在某處實現了該函數。如果鏈接程序找不到它,您將收到鏈接程序錯誤。

static void f(int n); 

聲明一個函數f,它取單個整數參數。靜態關鍵字使這個有趣。如果這是在.cpp文件中,該功能只對該文件可見。如果它在.h文件中,那麼包含該頭文件的每個.cpp文件都將創建該函數的副本,該副本只能由該實現文件訪問。

0

到目前爲止,這兩個答案都不贊成使用靜態函數。爲什麼?是什麼讓

命名空間{
void f(int n);
}

優於

靜態無效F(INT N);

?這並不簡單,它不容易理解......

0

匿名命名空間是一個更通用和更乾淨的解決方案,你可以有它的功能,變量,類。並且static在一些情況下意味着內部鏈接,在其他靜態生命週期中過度負載。
儘管匿名命名空間有一個缺點。由於外部鏈接,對象/庫文件的導出部分將隨着所有那些長期不會存在的名字而膨脹,這些名稱不會是靜態的。