2017-10-21 8 views
2

(この質問はグローバル+ユニークなオブジェクトが目標であることを前提としていますが、これは、シングルトンやグローバルを使用する/使用しないことを尋ねているわけではありません)。シングルトンの実装:シングルトンクラスよりもネームスペースのアプローチが望ましいことはよくありますか?

は、C++有効でシングルトンパターンの名前空間の実装です:私の質問があるので、私は欠けているCについての専門的++があるかどう

私は疑問に思って?もしそうなら、それがしばしばより良いアプローチとして提案されていない理由はありますか? Googleのスタイルガイドラインから

、我々は静的メンバ関数上で推奨される非メンバ関数を名前空間参照が、静的データを共有していないときにのみ:

「だけではなくグループの静的メンバ関数にクラスを作成 ました静的なデータを共有しないでください。代わりに名前空間を使用してください。 "

メンバー以外の関数に名前のない名前空間で宣言された静的なデータを共有させないようにするのはなぜですか?名前空間がC++でシングルトンクラスを書くより良い代替手段として一般に提案されていない理由を説明する、これについて何か間違っていますか?

私は名前空間のアプローチの勧告を見つけることができませんので、Cにもかかわらず、クラスのアプローチを見つけることは非常に容易である++クラスの使用を強制しませ:

C++ Singleton design pattern

Can any one provide me a sample of Singleton in c++?

Singleton instance declared as static variable of GetInstance method

http://www.aristeia.com/Papers/DDJ_Jul_Aug_2004_revised.pdf

Singleton: How should it be used

そのソース・ファイル内の無名の名前空間を持つという名前の名前空間を使用して:あなたは、静的なデータ

  • 経由「の状態」を持つことができます

    • あなたは無名の名前空間で物事を入れて、余分なプライバシーを得ることができます
    • 静的ポインタを使用し、関数呼び出しから構築することによって、静的オブジェクトの作成順序を制御することはできます。

      SingleThing.h:

      namespace single_thing // The singleton (if this is actually valid) 
      { 
          void GrowSomeCats(int amount); // Typical setter 
          int GetNumCats();    // Typical getter 
      } 
      

      SingleThing私が考えていた名前空間のアプローチの例 - あなたはシングルトンクラス


    編集を実装する必要はありません

  • 。CPP:

    #include "Balloon.h" 
    
    namespace // Acting like private members and functions 
    { 
        int numCats = 4;  // POD 
        Balloon* wilson = NULL; // Not POD (and not a singleton) 
    
        // Contrived 'private' function 
        bool CanGrowCats()  
        { return wilson && wilson->LikesCats(); } 
    
        // Contrived excuse to instantiate non-POD 'members' 
        void RandomlyCreateOtherObjects() 
        { 
         if (!wilson /* && someRandomiserImTooLazyToType()*/) 
          wilson = new Balloon(); 
        } 
    } 
    
    namespace single_thing // 'Public' functions 
    { 
        void GrowSomeCats(int amount) 
        { 
         RandomlyCreateOtherObjects(); 
         if (CanGrowCats()) 
          numCats += amount; 
        } 
    
        GetNumCats() 
        { return numCats; } 
    } 
    
  • +1

    これは、オブジェクト指向プログラミングのメリットについての質問です。関連する状態と関数を「クラス」にまとめる価値がありますか?私が思うシングルトンであるという事実も、ほとんど無関係です。 –

    +1

    これはスレッドセーフではありません。マイヤーのシングルトンを探してみることをお勧めします。 –

    +0

    多くのおかげです。 – Xenial

    答えて

    3

    (私たちはグローバルな状態は、特別な注意を払って使用する必要がある危険なものであることに同意することができますを前提としています。)

    技術的にはあなたのシングルトン名前空間がシングルトンクラスに相当します。しかし、それは1つの大きな欠点それは私の意見ではノーになります:それはステートフルであるという事実を隠します。これまで使用したstd::strtok()?それはひどい混乱を覚えていますか?それはそのステートフルなものも隠しているからです。

    グローバルな状態は本質的に危険であるため、それを使用する機能はコールサイトで十分に明確にする必要があります。言語構造を使用することをお勧めします。 A Foo::instance()->do_work();は、何か特別なことが起こっていることをはっきりさせる既知のパターンです。 foo::do_work();はありません。

    +0

    シングルトン/グローバルの前提に気を取られることなく、太字の2つの質問に感謝しています。今私は技術的に何かを間違っているわけではないが、それには意味のある欠点があることがわかる。 慎重な免責条項。 義務<どこにも何も悪い>免責事項。 – Xenial

    0

    シングルトンデザインパターン(役に立たないオブジェクトの作成で必要がない)の作成に関する有用なクラスの唯一のインスタンスです。 C++では、クラスはclassstructのキーワードで定義されています。作成と破壊に加えて、シングルトンクラスを有用にするには、インスタンスで動作するいくつかのメソッドも実装する必要があります。特異性を保証するために、シングルトンクラスはそのコンストラクタを非表示にし、インスタンスにアクセスするための静的メソッドを公開する必要があります。

    名前空間だけを使用すると、シングルトンの便利なメソッドを定義できなくなります。インスタンスアクセスメソッドをクラス自体の代わりにネームスペース内の関数として実装することは可能ですが、その関数には "friending"が必要であり、クラスが既に定義されているため意味がありません。

    非オブジェクトシングルトン(例えばプレーンデータ型の)を実装すると、インスタンスが構築を必要とせず、したがってシングルトンの必要がないと仮定します。

    +0

    名前空間のアプローチでは便利なメソッドを書くことができなかったのはなぜか分かりません。 – Xenial

    +0

    名前空間関数からインスタンスにアクセスする構想はどうですか? – hutorny

    +0

    (ちょうどその時にちょっと入力してください) あなたは 'インスタンス'について少し話しましたが、特定のインスタンスをまったく使用しない名前空間アプローチについて質問しています。 おそらく、シングルトンがコンセプトであるということを理解する価値があるかもしれません。シングルトンクラスはその実装の1つで、別の実装について質問しています。 明確にするためにQを編集します。 :) – Xenial

    関連する問題