C++ まとめ -言語編-

ページ内目録

名前(識別子)

名前

名前

C++で利用可能な名前は,1文字目が英字かアンダースコア(_)で,2文字目以降が英数字かアンダースコアである1文字以上文字列である.ただしアンダースコアから始まる識別子や二重のアンダースコアを含む識別子は,実装およびシステムエンティティのために予約されている.それゆえそれらの名前との競合を避けるため,そのような名前は使うべきでない. また,C++によって使用されるキーワードと同じ名前は使用できない.

キーワード

キーワードとは,言語の構成要素を表すために言語によって使用される識別子のことである.

  • and
  • and_eq
  • asm
  • auto
  • bitand
  • bitor
  • bool
  • break
  • case
  • catch
  • char
  • class
  • compl
  • const
  • const_cast
  • continue
  • default
  • delete
  • do
  • double
  • dynamic_cast
  • else
  • enum
  • explicit
  • export
  • extern
  • false
  • float
  • for
  • friend
  • goto
  • if
  • inline
  • int
  • long
  • mutable
  • namespace
  • new
  • not
  • not_eq
  • operator
  • or
  • or_eq
  • private
  • protected
  • public
  • register
  • reinterpret_cast
  • return
  • short
  • signed
  • sizeof
  • static
  • static_cast
  • struct
  • switch
  • template
  • this
  • throw
  • true
  • try
  • typedef
  • typeid
  • typename
  • union
  • unsigned
  • using
  • virtual
  • void
  • volatile
  • wchar_t
  • while
  • xor
  • xor_eq

C++では名前に含まれる字数については制限されていない. しかし,実装の一部(リンカなど)はコンパイラ開発者の管轄外であるため,実際にはそれらが字数制限を設けている場合はがある. また,一部の言語処理系には前述の文字以外を名前に利用できるものもある. ただしそのような名前を付けることは移植性のないプログラムを生む.

スコープ

宣言とは名前をスコープ(有効範囲)に入れる処理である. それゆえある名前はプログラムテキストの特定の部分でしか使用できない. スコープは宣言が行われたブロックによって決まる. ブロックとは{と}で囲われた文である. 名前は宣言された位置から宣言が行われたブロックの末尾まで利用できる. スコープは次の5種類に分類できる(分類はスッポスッポ先生のプログラミング本から).

グローバルスコープ
他の全てのスコープの外側のスコープ.グローバルスコープで宣言された名前を大域名や広域名といい,それ以外を局所名という.大域名は宣言された位置からファイル末尾まで有効である.
ファイルスコープ
グローバルスコープに似ているが,アクセス範囲が定義したファイル内に限定される。
名前空間スコープ
指定された名前のスコープがグローバルスコープまたは別の名前空間に入れ子になっているスコープ. 名前空間とは,C++が提供する宣言をグループ化する機能である. これにより,プログラマは関連する名前らを1つの名前空間スコープに割り当てることができる. 以下は,ColorとShape,Lineという画像処理を扱うためのクラスを宣言するためのサンプルである.
      
      namespace Graph_lib {
        class Color {/* ... */};
        class Shape {/* ... */};
        class Line {/* ... */};
      };
      
      
ここで用いられるクラス名のような簡潔で分りやすい名前は,コードを読みやすくするが,他で使用する名前と被りやすい. これは,他人のコードを併用する場合,より重要な問題となる. しかし名前空間を使用することで,そのような名前を使いつつも名前の競合を回避することができる. 名前空間に属する名前はスコープ演算子を使用することで,名前を指定できる(例:"Graph_lib::Color"). このような名前を完全修飾名と呼ぶ.
クラススコープ
クラスのメンバとして宣言された名前が属するスコープ.
ローカススコープ
あるブロック内側,または関数の引数リスト内で宣言された名前が属するスコープ.宣言位置からそのブロックの末尾まで有効.
文スコープ
ifやswitch,while,for文の中で宣言された名前が属するスコープ.宣言された位置からその文の末尾まで有効. その文の()の中で宣言したものもそのスコープに属する.

C++では,大域的名やあるブロックの外側のブロックで宣言した局所名らと同じ名前を持つ居所名を付けることができる(多重定義可能なものを除き,同じスコープの同じ名前はエラーである). そのような場合,その局所名を宣言してからそのブロックの末尾まで大域名は隠蔽される. つまり,ある大域変数xを宣言したファイルで局所変数xを宣言した場合,その局所変数が有効なスコープ内では,名前xは局所変数を指す. 隠蔽された大域変数xを指す場合,::(スコープ)演算子を使用する. 以下にその例を示す.


int x;
void function()
{
  int x = 0;
  ::x = 2; // 大域変数xに代入
  return;
}

また,ブロックを使用することで次のようにいつでも名前の隠蔽を行える.


int x;
void function()
{
  int x = 7;
  {
    int x = 10;    
  }
  return;
}

ただしこのような名前の隠蔽のためだけの入れ子構造はコードを複雑にするため,避けるべきである.

また,名前のスコープは宣言された位置より有効になるため,次のような無意味なコードを書けてしまう.

int x;
void function()
{
  int x = x; // 初期化されていない局所変数xで自身を初期化.
  return;
}

using宣言とusingディレクティブ

名前空間に属する名前は,usingキーワードを使うことで::(スコープ)演算子を省略できる. 省略方法には次の2つがある(前述で使用したGraph_lib名前空間を例として使用する).

using宣言
using宣言は,ある名前空間に属する名前に対し,using宣言を行ったスコープに同じ名前がなければ,宣言した名前の名前空間を省略できる.
     
using Graph_lib::Color;
using Graph_lib::Shape;

Color x;
Shape y;
     
     
usingディレクティブ
このスコープ内で見つからない場合は,指定した名前空間から検索する.
     
using namespace Graph_lib;

Color x;
Shape y;
     
     
usingキーワードを使用しすぎると,結局名前の競合を招く結果となる.

目録

キーワード

-緑の文字をクリック-