C++ 程式包含各種實體,例如變數、函式、類型和命名空間。 這些實體每一個都必須先宣告,才能加以使用。 宣告會指定實體的唯一名稱,以及其類型和其他特性的相關資訊。 在 C++ 宣告名稱的點,就是編譯器可見的點。 您無法參考編譯單位稍後宣告的函式或類別。 變數應該儘可能在接近使用的時間點之前宣告。
下列範例顯示一些宣告:
#include <string>
int f(int i); // forward declaration
int main()
{
const double pi = 3.14; //OK
int i = f(2); //OK. f is forward-declared
C obj; // error! C not yet declared.
std::string str; // OK std::string is declared in <string> header
j = 0; // error! No type specified.
auto k = 0; // OK. type inferred as int by compiler.
}
int f(int i)
{
return i + 42;
}
namespace N {
class C{/*...*/};
}
第 5 行宣告 main
函式。 第 7 行宣告名為 pi
的 const
變數,並將其初始化。 第 8 行宣告整數 i
,並以函式所產生的值初始化 f
。 編譯器可以看到名稱 f
,因為在第 3 行上的前向宣告。
在第 9 行中,宣告名為 C
類型的 obj
變數。 不過,此宣告引發錯誤,因為 C
在程式稍後才會宣告,而且不會前向宣告。 若要修正錯誤,您可以在 main
之前,先移動整個 C
的定義,或為其新增前向宣告。 此行為不同於其他語言,例如 C#。 在這些語言中,函式和類別可以在來源檔案中的宣告點之前使用。
在第 10 行中,宣告名為 std::string
類型的 str
變數。 std::string
的名稱是可見的,因為它是在 string
標頭檔中引進的,它會合併到第 1 行的原始來源檔案中。 std
是宣告 string
類別的命名空間。
在第 11 行中,因為名稱 j
尚未宣告,因此會引發錯誤。 宣告必須提供類型,不同於 JavaScript 等其他語言。 在第 12 行中,會使用 auto
關鍵詞,它會告知編譯器根據其初始化的值來推斷 k
的類型。 在此情況下,編譯器會針對類型選擇 int
。
宣告範圍
宣告所引進的名稱在宣告發生所在的範圍內有效。 在上一個範例中,main
函式內宣告的變數為局部變數。 您可以在 main 外部的全域範圍宣告名為 i
的另一個變數,而且會是個別的實體。 不過,這類名稱重複可能會導致程式設計人員混淆和錯誤,因此應避免。 在第 21 行中,類別 C
宣告在命名空間 N
的範圍中。 命名空間的使用有助於避免名稱衝突。 大部分 C++ 標準程式庫名稱都會在 std
命名空間內宣告。 如需範圍規則如何與宣告互動的詳細資訊,請參閱 範圍。
定義
某些實體,包括函式、類別、列舉和常數變數,必須定義及宣告。 定義提供編譯器在稍後程式使用實體時產生機器碼所需的所有資訊。 在上一個範例中,第 3 行包含函式 f
的宣告,但函式的定義在第 15 到 18 行提供。 在第 21 行上,類別 C
同時宣告和定義 (雖然如定義,類別不會執行任何動作)。 必須定義常數變數,換句話說,在宣告值的相同陳述式中指派值。 內建類型的宣告,例如 int
是自動定義,因為編譯器知道要為其配置多少空間。
下列範例顯示也是定義的宣告:
// Declare and define int variables i and j.
int i;
int j = 10;
// Declare enumeration suits.
enum suits { Spades = 1, Clubs, Hearts, Diamonds };
// Declare class CheckBox.
class CheckBox : public Control
{
public:
Boolean IsChecked();
virtual int ChangeState() = 0;
};
以下是一些不是定義的宣告:
extern int i;
char *strchr( const char *Str, const char Target );
Typedef 和使用陳述式
在舊版的 C++ 中,typedef
關鍵詞用來宣告另一個名稱別名的新名稱。 例如,std::string
類型是 std::basic_string<char>
的另一個名稱。 程序設計人員為何使用 typedef 名稱而非實際名稱,應該很明顯。 在新式 C++中,using
關鍵詞優先於 typedef
,但概念相同:已宣告和定義的實體會宣告實體的新名稱。
靜態類別成員
靜態類別資料成員是類別所有物件共用的離散變數。 因為它們是共用的,所以必須在類別定義之外定義和初始化。 如需詳細資訊,請參閱 類別。
外部宣告
C++ 程式可能包含多個編譯單位。 若要宣告在個別編譯單位中定義的實體,請使用 extern
關鍵詞。 宣告中的資訊就足以供編譯器使用。 不過,如果在連結步驟中找不到實體的定義,則連結器將會引發錯誤。
本節內容
儲存類別
const
constexpr
extern
初始設定式
別名和 typedef
using
宣告
volatile
decltype
C++ 中的屬性