c++の設計モードの1つ(単例モード)


実は私达はまずc++がどうしてこんなに多くの设计のモードがあることを考えるべきですか???
ある以上、それらは重要な役割を果たしている!!!
設計モードの役割:ある人がこのように言ったことを覚えています:設計モードの対象システム向けの設計と開発の役割はデータ構造のプロセス開発向けの役割のように、その役割がどんなに大きいかを見ることができます.
以下の機能があります.
(1)設計を再利用し,設計比重用コードを再利用することはより意味があり,コードの再利用を自動的にもたらす.
(2)設計に共通の語彙を提供し,各モード名は設計語彙であり,その概念はプログラマー間のコミュニケーションをより便利にする.
(3)開発文書にパターン語彙を採用することで、他の人があなたの考えを理解しやすくなり、なぜそうするのかを理解することができます.開発ドキュメントの作成が便利です.
(4)アプリケーション設計モードは、システムの再構築を容易にし、正しいコードの開発を確保し、設計や実装でエラーが発生する可能性を低減し、他のアプリケーションを書き換えて良いシステムフレームワークを提供することができる.
(5)設計パターンを正しく使うことで,多くの時間を節約できるなど.
まあ、菜鳥一枚では、C++23のデザインパターンの名前をはっきり呼ぶことはできません.ましてや理解はおろか、徐々に浸透しましょう.まず、ゆっくり理解して、これは骨髄に深く入り込んだものだと思います.私はまだ毛皮の上でうろうろしています.最近、この方面の本を読んで、いくつかのデザインパターンを見て、自分で強固にしたいと思っています.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
singletonモードはこれらのモードの中で最も簡単で、最も実現しやすいモードであり、面接官が最も聞きやすいモードでもあるのではないでしょうか.
単一のモードとは、クラスが1つのオブジェクトしか生成できないことです.これは重要です.例えば、プリンタのオブジェクト、一度に1つの作業中、1つのシステムに1つのウィンドウマネージャ、ダイアログボックス、ログオブジェクトなどがあります.
まず最初に見てみましょう
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class SingleTon
{
public:
    static SingleTon* getInstance()
    {
        return &singleTon;
    }
private:
    SingleTon(){}//                    
    static SingleTon singleTon;//      ,      ,             ,      ,      ,      
};
SingleTon SingleTon::singleTon;

2つ目:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class SingleTon
{
public:
    static SingleTon* getInstance()
    {
        static SingleTon singleTon; //      getinstance   ,      
        return &singleTon;
    }
private:
    SingleTon(){}
};
int main()
{
	return 0;
}
class SingleTon
{
public:
    static SingleTon* getInstance()
    {
        // gcc 4.6
        /*   static int count=0;
        static          
        
        if(!flag)
            lock();
            if(!flag)
                init
                flag=true;
            unlock();
        static               
               ******************
        */
        static SingleTon singleTon; 
        return &singleTon;
    }
private:
    SingleTon(){}
};

3つ目:
class SingleTon
{
public:
    //getInstance              ???
    //getInstance            ???
    static SingleTon* getInstance()
    {
       
        if(mpSingleTon == NULL)
        {
            mpSingleTon = new SingleTon();
        }
        return mpSingleTon;
    }
private:
    SingleTon(){}
    static SingleTon *mpSingleTon;
};
SingleTon *SingleTon::mpSingleTon=NULL;
では、このバージョンの単一のモードはスレッドが安全かどうか、つまりgetlnstanceという関数は関数に再入力可能かどうか、もしそうであれば、それはスレッドが安全で、そうでなければ、スレッドが安全ではありません.
mpSingleTon = new SingleTon();//この言葉が何をしたのか見てみましょう.
Newでは、メモリが割り当てられ、コンストラクション関数コンストラクションオブジェクトが呼び出されることを知っています.最後に、この文にアクセスするためにこの期間に異なるスレッドがあると思います.プロセスオブジェクトがまだ作成されていない場合、別のオブジェクトも作成されます.したがって、3つ目は単一スレッドで実行するのに適しています.マルチスレッドで使用する場合は、ロックをかけなければなりません.
class SingleTon
{
public:
    //getInstance              ???
    //getInstance            ???
    static SingleTon* getInstance()
    {
        pthread_mutex_lock(&mutex);
        if(mpSingleTon == NULL)
        {
            mpSingleTon = new SingleTon();
        }
        pthread_mutex_unlock(&mutex);
        return mpSingleTon;
    }
private:
    SingleTon(){}
    ~SingleTon(){pthread_mutex_destroy(&mutex, NULL);}
    static pthread_mutex_t mutex;
    static SingleTon *mpSingleTon;
};
pthread_mutex_t SingleTon::mutex = PTHREAD_MUTEX_INITIALIZER;
SingleTon *SingleTon::mpSingleTon=NULL;
このように書くと、もちろんスレッドは安全ですが、少し悪いです.このロックは重いと思います.空いているかどうかにかかわらず、先にロックをかけます.時間がかかります.ロックの位置を改善しなければなりません.
class CMutex//  
{
public:
    CMutex()
    {
        pthread_mutex_init(&mutex, NULL);
    }
    ~CMutex()
    {
        pthread_mutex_destroy(&mutex);
    }
    void lock()
    {
        pthread_mutex_lock(&mutex);
    }
    void unlock()
    {
        pthread_mutex_unlock(&mutex);
    }
private:
    pthread_mutex_t mutex;
};

class SingleTon
{
public:
    static SingleTon* getInstance()
    {
        if(mpSingleTon == NULL)
        {
            mutex.lock();   //      
            if(mpSingleTon == NULL)
                mpSingleTon = new SingleTon();
            mutex.unlock();
        }
        return mpSingleTon;
    }
private:
    SingleTon(){}
    ~SingleTon(){}
    static CMutex mutex;
    static volatile SingleTon *mpSingleTon;
};
CMutex SingleTon::mutex;
SingleTon *SingleTon::mpSingleTon=NULL;
のような二重ロック機構は、mpSingletonがNULLである場合にのみ、ロックを加えて一意のオブジェクトを作成する.別のスレッドがオブジェクトを作成しようとしたときにロックをかけます.
さて、ここまで、単例モードは終わり、さらに強固にしましょう.