2016-12-04 8 views
1

名前空間に関して、なぜそれらをいつも使うべきではないのでしょうか?すべてのヘッダー(.hpp)ファイルとすべてのソース(.cpp)ファイルに対して、名前空間内のすべてを宣言するのは良い方法です。別のファイルの名前空間内に何かを宣言したくないという状況がありますか?さらに、コンパイルは、クラスではなく関数に対して使用することができますか?私は現在、OpenGLを使ってゲームを開発しようとしていますが、現在main.cppに書かれている同じ機能を使用するクラスがいくつかあります。別の.hppファイルの名前空間でこれらの関数を宣言し、それらがクラスの一部ではないにもかかわらず対応する.cppファイルに実装するのは意味がありますか?いつ名前空間と別のコンパイルを使用する必要がありますか? (コンパイルをクラス外で使用することはできますか?)

それはこのようなものになります。単純に名前空間とクラスを置き換えるために、クラスでそれを実装するかしないかを説明するコメントと回答について :

// foo.hpp 
#ifndef FUNCTIONS_H 
#define FUNCTIONS_H 

namespace Functions 
{ 
    int function1(int x, int y, int z); 
    void function2(char* ex); 
    float function3(float a, float b, int c, int d); 
} 
#endif 

// foo.cpp 
#include "foo.hpp" 

int Functions::function1(int x, int y, int z) 
{ 
    // some code 
} 

void Functions::function2(char* ex) 
{ 
    // some code 
} 

float Functions::function3(float a, float b, int c, int d) 
{ 
    // some code 
} 

EDITを。明確にするために、これらのクラスのすべてが共通の祖先を継承するわけではないことに注意してください。したがって、関数を複数回書き直すことを回避しようとしています。私は伝統的なクラスを名前空間で完全に置き換えようとはしていません。静的なクラスでもこれを達成できることに言及しました。だから、私は静的なクラスを名前空間で置き換えるようなものだと思います。したがって、この時点での私の質問は、なぜこれが悪いことなのでしょうか?なぜ公的に使用される関数の名前空間に静的なクラスを使用するのですか?もちろん

// foo.hpp using class 
class Functions 
{ 
public: 
    static int function1(int x, int y, int z); 
}; 

// foo.hpp using namespace 
namespace Functions 
{ 
    int function1(int x, int y, int z); 
} 

// foo.cpp 
int Functions::function1(int x, int y, int z) // prepend static for use with class 
{ 
    // implementation 
} 

// someOtherFile.cpp 
    // some code 
    int value = Functions::function1(1,2,3); // same use 
    // more code 
+0

なぜ名前空間ですか?なぜクラスに入れないのですか?おそらく静的なクラスが必要です。 – user34660

+1

@ user34660これは名前空間が発明された理由です。 – juanchopanza

+0

そして、それはどのような授業が発明されたのかです。質問は非常に一般的です。関数がオブジェクトの一部であるように関連している場合は、クラスを使用する必要があります。 – user34660

答えて

1

、あなたが好きなnamespacesを自由に使用することが、あなたはすべてのソースファイルに対して異なる名前空間を使用することができます。彼らは、本質的に、私は間違っていないです場合、同じを使用することでしょう。しかし、私はこれが過度のものであり、コンパイル単位自体にある程度冗長かもしれないと思います。

名前空間の目標は、大きなプロジェクトで名前の衝突を避けることです。それは論理的に属しているアイテムを個々のクラスを超えてグループ化する方法です。通常、ライブラリ用に使用することができます(Stroustrupの本で説明されているように、versioningライブラリを含む)。または、何らかの種類のモジュール性(レイヤーごとに水平であるか、機能モジュールによって垂直であるかを問わず)を導入する。

もう1つの使用法は、cpp内でオブジェクトを非公開にすることができる匿名の名前空間です(ネストされているかどうかにかかわらず)。inaccessible from outside

私は思うが(それは個人的な見解である)、名前空間をクラスの代用として使うべきではない。例えば、クラスごとにコンパイル単位を持つというJavaのプラクティスをエミュレートする。むしろ物を梱包する方法と見なされるべきです。

EDIT:追加思考:あなただけ「の機能を書き換え回避複数回」したい場合は、関数は、原理的にはむしろ、いくつかのメンバ関数でなければなりません場合は、あなたが考えることができます:

  • を共通の祖先がある場合は、共通の祖先の関数メンバーにします。
  • CRTPを使用するか、またはあなたの機能のいくつかのバージョンを持っているしたい場合mixinクラス
  • でこれらの機能を入れて、使用する機能のセットを上静的または動的な構成を持っているのいずれか、共通の祖先がない場合は、各クラスを別のクラスに入れて使用するstrategy design pattern

一方、関数がロジッククラスから独立している場合は、それらを名前空間に入れることができます。私の主張は、クラスの代わりに名前空間を使用すること(つまり、ある種の抽象化には実際には対応しないクラスにいくつかの関数を置くこと)と、各コンパイル単位に対して異なる名前空間を作成することに反対していました。

+0

私は同じことを考えていたと思いますが(特に「大きなプロジェクト」と「個々のクラスを超えて」)、批判から自分自身を守る十分な経験がありません。 – user34660

+0

質問の編集を見ると、私はまだその意図を見ることができませんでした。だから親指のアドバイスの一般的なルールを超えて行くのは難しいです。それにもかかわらず、私はいくつかのクラスにfunctiosがいなければならない場合を示すセクションを追加しました。 – Christophe

関連する問題