29

名前空間を静的クラスとして使用することは良い習慣ですか? 例えば:

namespace MyStaticFunctions {
    void doSomething();
}

対:

class MyStaticFunctions {
    static void doSomething();
}
4

4 に答える 4

34

C++ には「静的クラス」のようなものはないため、C++ の観点からは、「静的クラスとして」ではなく、「名前空間として」使用しています。名前空間を使用して関数をグループ化することは、確かに受け入れられている方法です。

ただし、グループをどれだけ大きくしたいかはあなた次第です。C++ ライブラリがパブリック インターフェイス全体に対して単一の名前空間を使用することは珍しくありません。これは、(たとえば) Java に慣れている人にとっては驚くかもしれません。 Java では、多くの場合、少数の静的メソッドをグループ化するためにクラスが使用されます。C++ が最初に登場したので、Java はクラスを名前空間として使用していると言えます。

そのため、C++ では、静的メンバーでいっぱいのjava.util.Collectionsやに似たクラスを目にすることはあまりありません。java.lang.MathC++ のような関数のグループが必要な場合は、名前空間を使用します。

例外 (C++ には常に特別なケースがあるのではないですか?) はstd::numeric_limits<T>、テンプレート パラメーターが名前空間では実行できないことをクラスに実行させる のような特性型です。numeric_limitsfunction templates などを含むmax<T>()名前空間を定義することもできますmin<T>()が、それはあまり良くありません。まず、グループ化の方法が少し異なります。タイプTは「階層の下位」に表示されます。第二に、値を定義できる「オブジェクト テンプレート」のようなものがないため、特性タイプが行うすべてのことを行うわけではありませんnumeric_limits::digits<T>

静的クラスの実用的な使用法についてコメントするほど C# をよく知りませんが、知る限り、これは非静的メンバーを持たないように制限された単なるクラスであるため、これらの Java クラスに類似しています。

于 2013-01-16T15:11:59.047 に答える
22

C ++では、ケーニッヒのルックアップ(別名引数依存ルックアップ)のために、メソッドのみを含むのnamespaceではなく、言語レベルで使用することが実際に推奨されています。classstatic

例:

namespace geometry {
    struct Point { int x, y; };

    double distance_from_center(Point const& p) {
        return sqrt(p.x * p.x + p.y + p.y);
    }
} // namespace geometry

int main() {
    geometry::Point const p{3, 4}; // must qualify

    std::cout << distance_from_center(p) << "\n"; // not qualified
}

がメソッドdistance_from_centerとしてで記述されている場合は、毎回明示的に修飾する必要があります。staticclass

于 2013-01-16T15:22:12.063 に答える
8

個人的には難しくて興味深い質問なので、私の謙虚な意見を共有することにしました

「静的」クラス(静的メンバーのみ)と名前空間の違いを考慮する:

  1. 名前空間は複数のファイルに分散できます。柔軟性が向上しますが、慎重に使用する必要があります。
  2. 名前空間は引数依存のルックアップを提供します ( Matthieu M. answer を参照): 特定の状況で役立ちます
  3. 「静的」クラスはアクセス修飾子を持つことができ、階層を形成できます。クラスインターフェイスで宣言され、そのクライアントに表示されるプライベートメンバーは、論理的な理由ではなく技術的な理由によって決定されたC++の機能だと思います。プライベート静的メンバーの利点は見当たりません。「静的」階層の保護されたメンバー? 見たことがない。
  4. テンプレートメンバーに加えて、「静的」クラスは「テンプレート」になることができます。STLの優れた例については、Steve Jessopの回答を参照してください

メンテナンスの観点から、クラスを「静的」(シングルトンのように) にすることを決定する場合がありますが、要件が変更され、複数のインスタンスが必要になります。「静的」クラスは、名前空間よりも簡単に変換できます。

そして最後に、あなたの質問に答えるために:

「静的」クラスまたは名前空間の特別な機能が必要ない場合は、好きなものを使用してください:)

于 2013-01-16T15:51:59.947 に答える
4

場合によります。

メソッドは論理的にクラスに関連付けられていますか? その場合はメンバーにします。そうでない場合は名前空間に配置します。

機能的には同じですが、関数よりもコーディングする必要がありますよね? たとえば、クラスの名前を返すメソッドを考えてみます。

struct MyClass
{
    static std::string getName() { return "MyClass"; }
}

明らかに、メソッドを の外側に配置しnamespaceて同じ結果を得ることができますが、論理的にはクラスに属しています。

于 2013-01-16T15:08:24.587 に答える