函式原型和宣告的可見性
在 C++中,必須在使用前宣告或定義程式碼。例如,以下內容產生編譯時錯誤:
int main()
{
foo(2); // error: foo is called, but has not yet been declared
}
void foo(int x) // this later definition is not known in main
{
}
有兩種方法可以解決這個問題:在 main()
中使用 foo()
之前定義或宣告 foo()
。這是一個例子:
void foo(int x) {} //Declare the foo function and body first
int main()
{
foo(2); // OK: foo is completely defined beforehand, so it can be called here.
}
但是,也可以通過在使用之前僅放置原型宣告來轉發宣告該函式,然後再定義函式體:
void foo(int); // Prototype declaration of foo, seen by main
// Must specify return type, name, and argument list types
int main()
{
foo(2); // OK: foo is known, called even though its body is not yet defined
}
void foo(int x) //Must match the prototype
{
// Define body of foo here
}
原型必須指定返回型別(void
),函式名稱(foo
)和引數列表變數型別(int
),但不需要引數的名稱 。
將其整合到原始檔組織中的一種常用方法是建立包含所有原型宣告的標頭檔案:
// foo.h
void foo(int); // prototype declaration
然後在別處提供完整的定義:
// foo.cpp --> foo.o
#include "foo.h" // foo's prototype declaration is "hidden" in here
void foo(int x) { } // foo's body definition
然後,一旦編譯,將相應的目標檔案 foo.o
連結到編譯目標檔案中,在連結階段使用它,main.o
:
// main.cpp --> main.o
#include "foo.h" // foo's prototype declaration is "hidden" in here
int main() { foo(2); } // foo is valid to call because its prototype declaration was beforehand.
// the prototype and body definitions of foo are linked through the object files
當函式原型和呼叫存在時,會發生未解析的外部符號錯誤,但未定義函式體。由於編譯器在最後的連結階段之前不會報告錯誤,並且它不知道在程式碼中跳轉到哪一行來顯示錯誤,因此解決這些問題會更加棘手。