宣言と定義 (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
    std::string str; // OK std::string is declared in <string> header
    C obj; // error! C not yet declared.
    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 が宣言され、初期化 const。 8 行目では、整数 i が宣言され、関数 によって生成された値で初期化されます f 。 この名前 f は、3 行目の前方f宣言のため、コンパイラに表示されます。

9 行目では、 型の という obj 名前の変数 C が宣言されています。 ただし、この宣言は、 がプログラムの後半まで宣言されていないため、エラーが発生します。また、 は C 前方宣言されません。 このエラーを修正するには、 の定義全体を前に移動するか、それ以外の場合は前方 main 宣言を追加します。 この動作は、C# などの他の言語とは異なります。この言語では、ソース ファイル内の宣言ポイントの前に関数とクラスを使用できます。

10 行目では、 型の という str 名前の変数 std::string が宣言されています。 名前はヘッダー ファイル に導入され、1 行目のソース ファイルにマージされたため std::stringstringstd::string、表示されます。 std は、 クラスが宣言 string されている名前空間です。

11 行目では、名前が宣言されていないので、 j エラーが発生します。 宣言では、JavaScript などの他の言語とは異なり、型を指定する必要があります。 12 行目では、 キーワードが使用されます。このキーワードは、初期化に使用される値に基づいて の型を指定 autok します。 この場合、コンパイラは 型 int を選択します。

宣言のスコープ

宣言によって導入される名前は、宣言が 発生するスコープ 内で有効です。 前の例では、関数内で宣言されている変数は main ローカル main。 グローバル スコープ では、main の外部で という名前の別の変数を宣言できます。 i これは別のエンティティになります。 i ただし、このような名前の重複により、プログラマの混乱やエラーが発生する可能性があります。これは避ける必要があります。 21 行目では、 クラス C は 名前空間 のスコープで宣言されています N 。 名前空間を使用すると、名前の競合 を回避するのに役立ちます。 ほとんどの C++ 標準ライブラリ名は、 名前空間内で宣言 std されています。 スコープ ルールが宣言と対話する方法の詳細については、「スコープ」を参照 してください

定義

関数、クラス、列挙型、定数変数など、一部のエンティティを定義し、宣言する必要があります。 定義 、エンティティがプログラムの後半で使用される場合にマシン コードを生成するために必要なすべての情報をコンパイラに提供します。 前の例では、3 行目には関数の宣言が含まれているが、関数の定義は 15 行目から f 18 行目で指定されています。 f 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 と using ステートメント

以前のバージョンの C++ では、 キーワードを使用して、別の名前の別名である新 typedeftypedef を宣言します。 たとえば、 型は std::string の別の名前です std::basic_string<char> 。 プログラマが実際の名前ではなく typedef 名を使用する理由は明らかです。 最新の C++ では、 キーワードが より優先されますが、考え方は同じです。エンティティに対して新しい名前が宣言され、既に宣言および usingtypedef 定義されています。

静的クラス メンバー

静的クラス のデータ メンバーは、 クラスのすべてのオブジェクトによって共有される不連続変数なので、クラス定義の外部で定義および初期化する必要があります。 (詳細については、「クラス」を 参照してください)。

extern 宣言

C++ プログラムには、複数のコンパイル単位 が 含まれている場合があります。 別のコンパイル 単位で定義されているエンティティを宣言するには、 キーワードを使用 extern します。 宣言内の情報はコンパイラで十分ですが、リンク手順でエンティティの定義が見つからない場合、リンカーはエラーを発生します。

このセクションの内容

ストレージ クラス
const
constexpr
extern
初期化子
エイリアスと typedef
宣言
volatile
decltype
C++ の属性

関連項目

基本的な概念