スコープ (C)
クラス、関数、変数などのプログラム要素を宣言する場合、その名前は "表示" され、プログラムの特定の部分でのみ使用できます。 名前が表示されるコンテキストは、そのスコープと呼ばれます。 たとえば、関数内で変数 x
を宣言すると、x
は、その関数本体内でのみ表示されます。 ローカル スコープがあります。 プログラム内に同じ名前の他の変数がある場合があります。スコープが異なる限り、1 つの定義規則に違反し、エラーは発生しません。
自動非静的変数の場合、スコープによって、プログラム メモリ内でいつ作成および破棄されるのかも決定されます。
スコープには次の 6 種類があります。
グローバル スコープ グローバル名は、クラス、関数、または名前空間の外部で宣言された名前です。 ただし、C++ では、これらの名前も暗黙的なグローバル名前空間と一緒に存在します。 グローバル名のスコープは、宣言の時点から、宣言されるファイルの末尾まで拡張されます。 グローバル名の場合、可視性はリンケージの規則によっても制御され、プログラム内の他のファイルで名前が表示されるかどうかを判断します。
名前空間スコープ クラスまたは列挙型の定義または関数ブロックの外部にある名前空間内で宣言された名前は、宣言のポイントから名前空間の末尾まで表示されます。 名前空間は、異なるファイル間で複数のブロックで定義できます。
ローカル スコープ 関数またはラムダ内で宣言された名前 (パラメーター名を含む) には、ローカル スコープがあります。 多くの場合、"ローカル" と呼ばれます。 これらは、宣言の時点から関数またはラムダ本体の末尾にのみ表示されます。 ローカル スコープは、この記事で後で説明するブロック スコープの一種です。
クラス スコープ クラス メンバーの名前には、宣言のポイントに関係なくクラス定義全体に拡張されるクラス スコープがあります。 クラス メンバーのアクセシビリティは、
public
、private
、およびprotected
キーワードによって、さらに制御されます。 パブリック メンバーまたは保護されたメンバーには、メンバー選択演算子 (. または ->) またはポインターからメンバーへのポインター演算子 (.* または ->*) を使用した場合にのみアクセスできます。ステートメント スコープ
for
、if
、while
、またはswitch
ステートメントで宣言された名前は、ステートメント ブロックの末尾まで表示されます。関数スコープ A ラベル には関数スコープがあります。つまり、宣言ポイントの前でも関数本体全体で表示されます。 関数スコープを使用すると、
cleanup
ラベルが宣言される前にgoto cleanup
のようなステートメントを記述できます。
名前の隠ぺい
囲まれたブロック内で名前を宣言すると、その名前が非表示になります。 次の図では、内側のブロックで i
が再宣言されています。そのため、外側のブロック スコープでは i
に関連付けられた変数が隠し変数になります。
ブロック スコープおよび名前の非表示
このプログラムの出力を次の図に示します。
i = 0
i = 7
j = 9
i = 0
Note
szWhat
引数は、この関数のスコープ内にあると見なされます。 したがって、この関数の外側のブロックで宣言されたものとして処理されます。
クラス名の非表示
関数、オブジェクト、変数、または列挙子を同じスコープ内で宣言することで、クラス名を非表示にできます。 ただし、class
キーワードを先頭に付加すれば、非表示にしたクラス名にアクセスできます。
// hiding_class_names.cpp
// compile with: /EHsc
#include <iostream>
using namespace std;
// Declare class Account at global scope.
class Account
{
public:
Account( double InitialBalance )
{ balance = InitialBalance; }
double GetBalance()
{ return balance; }
private:
double balance;
};
double Account = 15.37; // Hides class name Account
int main()
{
class Account Checking( Account ); // Qualifies Account as
// class name
cout << "Opening account with a balance of: "
<< Checking.GetBalance() << "\n";
}
//Output: Opening account with a balance of: 15.37
Note
クラス名 (Account
) を呼び出すときは、ファイル スコープ変数 Account と区別するため、class キーワードを使用する必要があります。 スコープ解決演算子 (::) の左側がクラス名の場合は、この規則が適用されません。 スコープ解決演算子の左側の名前は、常にクラス名と見なされます。
次に、class
キーワードを使用して、Account
型のオブジェクトへのポインターを宣言する方法を例示します。
class Account *Checking = new class Account( Account );
上記のステートメントで、初期化子の (かっこで囲まれた) Account
はグローバル スコープで double
型です。
Note
この例のように、識別子名を再使用するのは適切なプログラミング方法ではありません。
クラス オブジェクトの宣言と初期化については、「クラス、構造体、共用体」を参照してください。 フリー ストア演算子 new
および delete
の使用方法については、「new および delete 演算子」を参照してください。
グローバル スコープでの名前の非表示
ブロック スコープで同じ名前で明示的に宣言して、グローバル スコープを持つ名前を非表示にすることができます。 ただし、スコープ解決演算子 (::
) を使用して、ファイル スコープ名にアクセスできます。
#include <iostream>
int i = 7; // i has global scope, outside all blocks
using namespace std;
int main( int argc, char *argv[] ) {
int i = 5; // i has block scope, hides i at global scope
cout << "Block-scoped i has the value: " << i << "\n";
cout << "Global-scoped i has the value: " << ::i << "\n";
}
Block-scoped i has the value: 5
Global-scoped i has the value: 7
関連項目
フィードバック
https://aka.ms/ContentUserFeedback」を参照してください。
以下は間もなく提供いたします。2024 年を通じて、コンテンツのフィードバック メカニズムとして GitHub の issue を段階的に廃止し、新しいフィードバック システムに置き換えます。 詳細については、「フィードバックの送信と表示