第50章 異姓同名

 CAAA クラスのメンバ AAA と CBBB クラスのメンバ AAA とは区別がつきます。今回はこれと似たような仕組みについて話そうと思います。


 では、今回の要点です。


 では、いってみましょう。


 ある他人の作ったライブラリを利用したいと思います。しかし、そのライブラリの中には CFile クラスがあるとします。この CFile を切り離して使えないようになっていれば、自分の CFile を使いたいときに困りますね。

 こういう場合、自分の CFile の名前を CMyFile などに変えれば済む話ですが、CFile を全部 CMyFile に変えるのも面倒な話です。

 こういったことを避けるために、普段から名前空間という機構を使っておくと便利かもしれません。名前空間は、あるときは CMyFile のように、あるときは CFile のように使えるようにする機構です。普段は CFile で使うようにしておいて、名前の衝突するときだけ CMyFile のような形で使えばいいわけです。


 では、とりあえず実際に使っているプログラムを見てみて下さい。

プログラム1
// Name1.h
#ifndef __NAME1_H__010407_1554_70554750__INCLUDED__
#define __NAME1_H__010407_1554_70554750__INCLUDED__

namesapce Name1
{
    void Func();
}

#endif // #ifndef __NAME1_H__010407_1554_70554750__INCLUDED__
プログラム2
// Name1.cpp
#include <iostream.h>

namesapce Name1
{
    void Func()
    {
        cout << "Name1::Func" << endl;
    }
}
プログラム3
// Name2.h
#ifndef __NAME2_H__010407_1556_57951860__INCLUDED__
#define __NAME2_H__010407_1556_57951860__INCLUDED__

namesapce Name2
{
    void Func();
}

#endif // __NAME2_H__010407_1556_57951860__INCLUDED__
プログラム4
// Name2.cpp
#include <iostream.h>

namesapce Name2
{
    void Func()
    {
        cout << "Name2::Func" << endl;
    }
}
プログラム5
// Name3.cpp
#include "Name1.h"
#include "Name2.h"

int main()
{
    Name1::Func();
    Name2::Func();

    return 0;
}
実行結果
Name1::Func
Name2::Func

 namesapce Name1 というのが名前空間の指定になります。Name1 が名前空間名になります。そのあとの { } で囲まれた中にある名前は Name1::<名前> のように使うようになります。これがさっき言った「CMyFile のように使う」にあたるわけです。

 このように、ある共通した名前空間名を持つ空間のことを名前空間と呼びます。名前空間が違えば、本来はオーバーロードできないはずの2つの void Func() も、2つとも定義することができます。

 名前空間名を名字のような感じに考えてもいいかも知れません。同じ「雅樹」でも「佐藤雅樹」と「加持雅樹」では区別がつきますね。


 しかし、雅樹が1人しかいないのであれば、わざわざ名字を呼ぶ必要はありません。そこで、名前空間名を省略することもできます。

プログラム6
// Name3b.cpp
#include "Name1.h"
#include "Name2.h"

using namespace Name1;

int main()
{
    Func();
    Name2::Func();

    return 0;
}
実行結果
Name1::Func
Name2::Func

 このように、using namespace <名前空間名>と書くことで、以降可能な限り Name1 を省略することができるようになるのです。

 では、両方とも省略できるようにしたらどうなるのでしょうか? そのときは、Func とだけ書いてもどちらの Func かサッパリ分かりません。なので、名前空間名を指定してやる必要が出てきます。しかし、衝突しない限りは省略することができるわけです。

 では、もう1つ、名前空間を指定していないところはどうなっているのでしょうか? それは名前無しの名前空間であるグローバルネームスペースに属することになります。つまり、グローバルネームスペースの関数を呼びたいときは ::Func() のように、名前空間名を書かずに :: だけを書きます第1部第68章でグローバル変数を使うために :: つけましたが、これもグローバルネームスペースの指定をしていることになります。

 グローバルネームスペースは最初から省略できるので、比較的名前が衝突しやすくなります。なるべく名前は何らかの名前空間に属すようにしておくのがいいと思います。

 名前空間を作っておけば名前の衝突を気にする必要がほとんどなくなります。名前空間名自体が衝突すると...それはどうにもならないので(汗)、なるべく衝突しないような名前にして下さい。どうせ普段は省略できて、衝突することも滅多にないのが普通なので、少しくらいは変わった名前にしても構わないかもしれません。


 では、今回の要点です。


 これで第2部は終了です。第4部からは std 名前空間やSTLについて話していきたいと思います。もう言語の話からは離れて、ライブラリの使い方の話になりますね。クラスについての話では多重継承が残っていますが、これは高度な話になるので第3部で話したいと思います。

 それでは、また第4部で会いましょう。


第49章 えっ!? 5 | 第4部第1章 業界のスタンダード

Last update was done on 2001.4.7

この講座の著作権はロベールが保有しています