トップ->C++入門

あなたは

人目のC++(C)言語入門受講生です。

C++入門内検索

目次
C++入門〜トップ
C言語入門〜トップ
0. はじめに

1. オブジェクト指向とは?
   1. オブジェクト指向とクラス
   2. 継承
   3. カプセル化
   4. ポリモーフィズム

2. ストリーム
   1. 出力
   2. マニピュレータ
   3. 入力
   4. ファイル
   5. 練習問題1
   6. 文字列
   7. 練習問題2

3. C++の新しい文法
   1. 新しい型bool
   2. デフォルト引数
   3. newとdelete
   4. 参照型
   5. const
   6. 変数の宣言
   7. 例外
   8. オーバーロード
   9. テンプレート関数
   10. 名前空間

4. クラス
   1. クラスとは
   2. クラスの宣言
   3. クラスの実装
   4. コンストラクタとデストラクタ
   5. クラスの使用法
   6. 例題)スタッククラス
   7. テンプレートクラス
   8. 練習問題
   9. 参照型
   10. 代入演算子
   11. コピーコンストラクタ
   12. 構造体
   13. メンバー変数の初期化
   14. 内部クラス
   15. 無名クラス
   16. 無名共用体
   17. 演算子の作り方
   18. friend
   19. 練習問題
   20. クラス変数(静的変数)
   21. 静的関数
   22. クラスと関数ポインタ

5. クラスの包含
   1. 包含とは
   2. クラスの作成・破壊
   3. メンバーイニシャライザ
   4. ポインタによる包含
   5. 参照による包含
   6. 練習問題

6. 継承
   1. 継承とは
   2. スーパークラスのコンストラクタ
   3. 継承とキャスト
   4. スコープ
   5. クラスの作成・破壊
   6. 派生の種類
   7. 仮装関数
   8. 純粋仮装関数
   9. 仮装デストラクタ
   10. 例題)例外クラス
   11. V-table(VF-table)
   12. 例題)お絵かきソフト
   13. 継承と包含
   14. 多重継承
   15. 多重継承の用途
   16. 仮想クラス
   17. 実行時型情報(RTTI)
   18. dynamic_cast

7. STL
   1. STLとは
   2. STLの歴史
   3. STLの構成
   4. コンテナ
   5. vector
   6. イタレーター
   7. クラスとSTL
   8. list
   9. queue
   10. deque
   11. priority_queue
   12. stack
   13. map
   14. mutimap
   15. set
   16. multiset
   17. bitset
   18. アルゴリズム
   19. basic_string
   20. コンテナを作ろう
   21. アルゴリズムを作ろう
   22. 配列とアルゴリズム

8. その他
   1. 変数名について

9. その後は
   1. ヒューマンアカデミー C言語講座
   2. el school C言語講座


・ トップページに戻る



・ トップページに戻る

トップ-> C++入門:3章 C++の新しい文法-> 名前空間

←前ページへ :  トップへ :  次章へ→

10. 名前空間

  C言語の標準関数をすべて覚えている人は滅多にいないと思います。さらにC++では 標準関数やクラスが増えたため、標準で定義されている識別子をすべて覚えることは 不可能に近いです。そんな中で、関数や変数を作ろうとした場合、標準で定義されている関数名と 名前がバッティングすることも少なくありません。

  現に、C++が登場した頃は、標準関数と同じ名前で、同じ引数リストを持つ関数を作って しまい、標準関数を呼びたかったのか、自分が作った関数を呼びたかったのかわからなく なったり、予期しないバグにぶち当たることも多々ありました。

  そこで考えられたのが「名前空間」です。名前空間とは、関数名などの識別子の 名前をどこで管理するかを決める機構です。

  例えば、全国に「山田太郎」さんという名前の人が10人いたとします。しかし、 「東京の山田太郎さん」と指定すれば1人かもしれません。この「東京の」にあたるのが 名前空間です。

  実際は電話番号に近いかもしれません。例えば、全国に「12-3456」という電話番号が 10件あったとします。しかし、市外局番をつけて「0468-12-3456」と指定すれば、それは 必ず1件しかありませんこの「市外局番」にあたるのが名前空間です。

  名前空間を作るためには以下のように宣言します。

namespace name{
    // 宣言
}

例) namespace Tokyo{ int yamada_taro; }

  名前空間を使用した例を示します。
#include<iostream>
using namespace std;

namespace Tokyo{
    const char* Yamada = "Yamada Taro";

    // TokyoのPrintName関数
    void PrintName(const char* name){
        cout << name << endl;
    }

    // TokyoのPrintName関数
    void PrintName(){
        cout << Yamada << endl;
        // Tokyoの中ではTokyo::と指定しなくてもいい
        // 同じ東京内では市外局番を省略できるのと同じ
    }
}

// グローバルなPrintName
void PrintName(const char* name){
        cout << name << "  " << name << endl;
}

void main(){
    // グローバルなPrintNameを呼ぼうとしている
    PrintName(Yamada);          // エラー:どこのYamadaさんだかわからない

    // グローバルなPrintNameを呼ぼうとしている
    PrintName(Tokyo::Yamada);   // OK:TokyoのYamadaさんを指定している

    // TokyoのPrintNameを呼ぼうとしている
    Tokyo::PrintName("Suzuki");
}

  上記の例のアンダーラインのように「::」演算子を用いて、どこの名前空間に所属しているかを 指定することで、目的の名前空間にアクセスすることができます。ただし、同じ名前空間内では 省略することができます。同じ市内では市外局番を省略できるのと同じ考えです。

  しかし、いちいち名前空間を指定するのは面倒です。例えば東京の山田太郎さんが親戚ならば、 親戚内では「山田太郎さん」と言えば、親戚の山田太郎さんであることは「東京の」と付け加えなくても わかります。

#include<iostream>
using namespace std;

namespace Tokyo{
    const char* Yamada = "Yamada Taro";

    // TokyoのPrintName関数
    void PrintName(const char* name){
        cout << name << endl;
    }
}

// グローバルなPrintName
void PrintName(const char* name){
        cout << name << "  " << name << endl;
}

// これ以下は、Tokyo::と付けなくても、暗黙でTokyoを調べてくれる
using namespace Tokyo;

void main(){
    // さっきはどこのYamadaさんだかわからなかったが、今回はTokyoのYamadaさんだとわかる
    // しかし、PrintNameがTokyoのPrintNameだか、グローバルなPrintNameだかわからないので
    // エラー
    PrintName(Yamada);

    // TokyoのPrintNameを呼ぼうとしている
    // これはOK
    Tokyo::PrintName(Tokyo::Yamada);

    // グローバルなPrintNameを呼ぼうとしている
    // これもOK
    ::PrintName("Suzuki");
}

  上記のアンダーラインのように暗黙で名前空間を指定したい場合はこのように記述します。

  暗黙で指定できる名前空間は1つではなく、2つ以上可能です。例えば上述の例では2行目で指定している C++の標準関数用名前空間「std」と、自分で指定した(アンダーラインの部分)の「Tokyo」と2つの名前空間を 指定しています。もしこの2つの名前空間に同じ名前の関数や変数などがあった場合は「std::???」というように 指定しなければなりません。


#include<iostream>
using namespace std;

namespace Tokyo{
    const char* Yamada = "Yamada Taro";

    // TokyoのPrintName関数
    void PrintName(const char* name){
        cout << name << endl;
    }
}

// グローバルなPrintName
void PrintName(const char* name){
        cout << name << "  " << name << endl;
}

// これ以下は、Tokyo::と付けなくても、暗黙でYamadaだけはTokyoを調べてくれる
using Tokyo::Yamada;

void main(){
    // 今回は、TokyoのPrintNameは見えておらず、グローバルなPrintNameのみ見えているので
    // YamadaはTokyo::を見てくれる
    // OK
    PrintName(Yamada);

    // TokyoのPrintNameを呼ぼうとしている
    // これはOK
    Tokyo::PrintName(Tokyo::Yamada);

    // グローバルなPrintNameを呼ぼうとしている
    // YamadaはTokyo::を見てくれる
    // これもOK
    ::PrintName(Yamada);
}
Yamada Taro  Yamada Taro
Yamada Taro
Yamada Taro  Yamada Taro

  ある特定の変数や関数だけを暗黙で指定したい場合は、上記のアンダーラインのように 記述します。


  名前空間に含めることができるのは、変数や関数だけではありません。クラス宣言自体を 名前空間に納めることもできます。

  上でも述べたようにC++の標準ライブラリは「std」という名前空間に納められています。つまりcoutなど 標準で用意されているものを使う場合には、「using namespace std;」と記述するか、「std::cout」という ように書かなくてはなりません。



←前ページへ :  トップへ :  次章へ→