名前空間を使用する - C++ プログラミング

PROGRAM


名前空間を定義する

C++ でクラスや関数・変数などを定義するときに、名前空間というものが利用できます。

この名前空間を使うことで、もし他で同じ名前のクラスや関数・変数が定義されていてもそれとの衝突が避けられるので、さまざまなライブラリを使ってプログラムを組む場合や、誰かに使ってもらうためのライブラリを作成するようなときに重宝します。

 

名前空間の定義は、通常はヘッダーファイルで namespace キーワードを使用します。

namespace MySpace

{

class CMyClass

{

public:

void toString() const;

};

 

class COurClass

{

public:

void toString() const;

};

}

このように、namespace キーワードに続けて空間名を指定して、ブロックで括ります。

こうすることで、このブロック内に定義された CMyClass クラスは、名前空間 MySpace に所属するクラスとして扱われ、もし CMyClass という名前のクラスが他の場所で定義されていたとしても、それとは別のものとして扱われます。

 

名前空間で定義したものを使用する

名前空間内で定義されたクラスや関数・変数は、その定義名の前に "空間名::" を付けることで使用できます。

MySpace::CMyClass* myClass;

例えば MySpace 名前空間で定義した CMyClass クラスのポインタを格納する変数 myClass を定義するのであれば、上記のような感じになります。

慣れないと複雑に見えるかもしれませんが、要はデータ型が MySpace::CMyClass になっているだけです。

ちなみにここで使用している "::" という記号は、スコープ解決演算子と呼ばれるようです。

 

クラスのメソッドを実装するときには、通常は実装ファイル内で "クラス名::メソッド名" という形で宣言しますけど、ここにも名前空間は影響してきます。

void MySpace::CMyClass::toString() const

{

}

このように、どの名前空間のどのクラスのどのメソッドであるかということが明示的に区別されます。

 

もっと簡単に使用できるようにする

使用するものを明記する方法

名前空間内で定義されたクラスや関数・変数は、使用するものを using キーワードを使って列挙することで、それらについては名前空間を指定せずに使うことができるようになります。

using MySpace::CMyClass;

名前空間というのはそもそも衝突を避ける仕組みですから、こういった記載は、通常は実装ファイルの方に記載することになります。

 

このようにすることで、この using 行が書かれた以降は、名前空間を省略して記載することができるようになります。

CMyClass* myClass;

名前空間を使わなかったときと同じ書き方で使えるようになりました。

名前空間を指定しなくても良くなったといっても、名前空間から外れたわけではないので、このファイルが関係しない別のところに同じ名前のクラスがあってもそちらには影響ありません。また、相変わらず "MySpace::CMyClass" という書き方も出来ます。

 

ちなみに、今回の例では MySpace 名前空間にもうひとつ COurClass が定義されていますが、こちらは using キーワードで明示していないので、名前空間を省略することはできません。

 

省略できる名前空間を明記する方法

頻繁に使用する名前空間名は using namespace キーワードを使うと、その名前空間名を省略できるようになります。

using namespace MySpace;

こちらは、先ほどの使うものだけ列挙する方法よりもさらに強力なので、少なくともヘッダーファイル内に記載することはないと思います。ヘッダーファイルに記載してしまうと、名前空間そもそもの忌が無くなってしまいかねないので注意してください。

 

このようにしても、この using namespace 行が書かれた以降は、その名前空間を省略して記載することができるようになります。

CMyClass* myClass;

名前空間を使わなかったときと同じ書き方で使えるようになりました。

今回の using namespace の場合は、名前空間 MySpace 自体を省略できるので、先ほどの using だけの場合とは違って、同じ名前空間に所属している COurClass についても、名前空間を省略できるようになっています。

 

名前空間を入れ子にする

名前空間は、入れ子にして定義することができます。

namespace MySpace

{

namespace Sample

{

class CMyClass

{

public:

void toString() const;

};

}

}

このように定義すると、MySpace 名前空間の Sample 名前空間にある CMyClass というようになります。

使い方もこれまでと一緒で、名前空間の階層の数だけ "::" で区切って名前空間名を付けるようにします。

MySpace::Sample::CMyClass* myClass;

using キーワードや using namespace キーワードも、入れ子にした場合も同じように使用できます。

 

名前空間のエイリアスを作成する

C++ では名前空間の別名を定義することもできるようになっています。

namespace MyAlias = MySpace;

このようにすることで、名前空間名 MySpace に定義されているもののすべてが、MyAlias 名前空間のものとしても使えるようになります。

MyAlias::Sample::CMyClass* myClass;

これまでの名前空間がなくなるわけではないので、従前どおりの名前空間を使い続けることもできます。

 

名前空間にエイリアスを設定する用途というのは、名前空間を短くして簡単に書けるようにするというくらいなのでしょうか。

あまり役に立つものではない気がします。

 

無名名前空間を使用する

C++ には無名名前空間 (unnamed namespace) というものがあります。

namespace を名前空間名を指定せずに使用する方法なのですが、これを使用することで、そのファイルでだけ使用できるクラスや関数・変数を用意することができるようになっています。

ファイルだけで使用できるということなので、実装ファイル内に記載することになります。

namespace

{

int coefficient;

}

たとえばこのようにすることで、このファイル内でだけ使用できるグローバル変数 coefficient を定義することができました。

 

このように変数を定義した場合は、 C 言語で言う "static int coefficient" という記述と同じ動きになります。

ただし static キーワードはもともと変数の保存方法(記憶クラス)を静的 (static) にするためのものなので、C++ に言わせれば、ファイル内だけで使用する大域変数は無名名前空間内で宣言するのが適切な実装方法になるようです。


[ もどる ]