宣告和定義 (C++)

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 上, const 會宣告並 初始化名為 pi 變數。 在行 8 上,會 i 宣告整數,並以 函式 所產生的 f 值初始化。 編譯器可以看到名稱 f ,因為 第 3 行的正向宣告

在行 9 中,會宣告名為 obj 類型的 C 變數。 不過,此宣告會引發錯誤,因為 C 直到稍後才在程式中宣告,而且不會向前宣告。 若要修正錯誤,您可以先移動 的整個 定義 Cmain 或為其新增正向宣告。 此行為不同于其他語言,例如 C#。 在這些語言中,函式和類別可以在來源檔案中的宣告點之前使用。

在行 10 中,會宣告名為 str 類型的 std::string 變數。 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 );

Typedefs 和 using 語句

在舊版的 C++ 中, typedef 關鍵字是用來宣告新名稱,該名稱是另一個名稱的 別名 。 例如,類型 std::string 是 的另 std::basic_string<char> 一個名稱。 程式設計人員為何使用 typedef 名稱而非實際名稱,這應該很明顯。 在新式 C++ 中 using ,關鍵字優先于 typedef ,但概念相同:已宣告並定義實體的新名稱。

靜態類別成員

靜態類別資料成員是類別所有物件共用的離散變數。 因為它們是共用的,所以必須在類別定義之外定義和初始化它們。 如需詳細資訊,請參閱 類別

extern 宣告

C++ 程式可能包含一個 以上的編譯單位 。 若要宣告在個別編譯單位中定義的實體,請使用 extern 關鍵字。 宣告中的資訊就足以供編譯器使用。 不過,如果在連結步驟中找不到實體的定義,則連結器將會引發錯誤。

本節內容

儲存類別
const
constexpr
extern
初始設定式
別名和 typedef
using 聲明
volatile
decltype
C++ 中的屬性

另請參閱

基本概念