C++設計モードの単例モード学習及び連想......

10480 ワード

上級者のコードの中で単例のモードを見て、とても面白いと思って、先に整理して勉強して、それから自分の知識を利用して連想して、:).
単一のモードは、エンジニアリングでは、1つのオブジェクトしかインスタンス化できません.このオブジェクトは、グローバルに共有されています(includeのようなヘッダファイルだけでいいです).
まず、単一のモードの実装を見てみましょう.
#include<stdio.h>
#include<iostream>
using namespace std;


class Singleon
{
public:
        static string param;
        static Singleon& getinstance()
        {
                if(s == NULL)
                {
                        s = new Singleon();
                }
                return *s;
        }

        void Print(const char* str)
        {
                cout << "singleon str:" << str <<endl;
        }
private:
        Singleon(){};
        static Singleon *s;

};
Singleon* Singleon::s = NULL;
int main()
{
        Singleon::getinstance().Print("test");
        Singleon::getinstance().Print("test1");
        return 0;
}

上記のコードでは、Singleonクラスを2回呼び出す方法Printが、1つのオブジェクトのみを生成し、一般的なクラスの実装に従って2つのオブジェクトを生成し、そのメソッドを呼び出すことができます(もちろん、この例では、1つのオブジェクトについて、複数の.cppファイルであれば、その威力を見ることができます).
このコードをコンパイルして、コードをファイル名:mainに保つことができます.cpp、コンパイルは以下の通りです.
g++ main.cpp -o main
valgrind ./main
==5627== Memcheck, a memory error detector
==5627== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==5627== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==5627== Command: ./mainj
==5627== 
singleon str:test
singleon str:test1
==5627== 
==5627== HEAP SUMMARY:
==5627==     in use at exit: 1 bytes in 1 blocks
==5627==   total heap usage: 1 allocs, 0 frees, 1 bytes allocated
==5627== 
==5627== LEAK SUMMARY:
==5627==    definitely lost: 0 bytes in 0 blocks
==5627==    indirectly lost: 0 bytes in 0 blocks
==5627==      possibly lost: 0 bytes in 0 blocks
==5627==    still reachable: 1 bytes in 1 blocks
==5627==         suppressed: 0 bytes in 0 blocks
==5627== Rerun with --leak-check=full to see details of leaked memory
==5627== 
==5627== For counts of detected and suppressed errors, rerun with: -v
==5627== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 6)

注意深く私たちは、メモリの割り当て(以下)があり、プログラムが実行され、まだ解放されていないことを簡単に見ることができます.どうすればいいですか.
==5627==   total heap usage: 1 allocs, 0 frees, 1 bytes allocated
プログラムでnewインスタンス化オブジェクトを使用するには、deleteを使用してオブジェクトを解放する必要があります.最初から最後までdeleteを使用していません.の
1つの方法は、オブジェクトをインスタンス化した後、deleteを直接使用することです.この方法には、いつdeleteを使用するかという問題があります.毎回deleteを使用すると、その代価が大きすぎて、マルチスレッドプログラムでは、エラーが発生しやすいです.
次に、newのインスタンス化オブジェクトを空にするためのクラスを単一のインスタンス化クラスで定義する方法について説明します.
#include<stdio.h>
#include<iostream>
using namespace std;


class Singleon
{
public:
        static string param;
        static Singleon& getinstance()
        {
                if(s == NULL)
                {
                        s = new Singleon();
                }
                return *s;
        }

        void Print(const char* str)
        {
                cout << "singleon str:" << str <<endl;
        }
private:
        class Cleaner
        {
                ~Cleaner()
                {
                        if(s != NULL)
                                delete s;
                }
        };
        static Cleaner clr;
        Singleon(){};
        static Singleon *s;

};
Singleon* Singleon::s = NULL;
Singleon::Cleaner Singleon::clr;
int main()
{
        Singleon::getinstance().Print("test");
        Singleon::getinstance().Print("test1");
        return 0;
}

単一クラスSingleonでCleanerクラス(以下)を定義し、その静的オブジェクトをインスタンス化し、プログラム終了時に構造関数を自動的に呼び出し、deleteを呼び出すことができます.
class Cleaner         {                 ~Cleaner()                 {                         if(s != NULL)                                 delete s;                 }         };
static Cleaner clr;
Singleonクラスの外側にはclrを初期化する必要があります.
Singleon::Cleaner Singleon::clr;
今ではこの単例類SingleonがOKとなっており、ご自由にお使いいただけます.念のため、メモリ検出の結果を見てみましょう.
valgrind ./main
==15732== Memcheck, a memory error detector
==15732== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==15732== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==15732== Command: ./mainj
==15732== 
singleon str:test
singleon str:test1
==15732== 
==15732== HEAP SUMMARY:
==15732==     in use at exit: 0 bytes in 0 blocks
==15732==   total heap usage: 1 allocs, 1 frees, 1 bytes allocated
==15732== 
==15732== All heap blocks were freed -- no leaks are possible
==15732== 
==15732== For counts of detected and suppressed errors, rerun with: -v
==15732== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 6)

次のようになります.
==15732==   total heap usage: 1 allocs, 1 frees, 1 bytes allocated ==15732==  ==15732== All heap blocks were freed -- no leaks are possible
クラスが単一のクラスである場合は、上記の定義を直接使用して大丈夫です.複数のクラスがある場合、各クラスはこのように定義する必要がありますか?コードの重複は多くなります.
抽象的に、共通のものをbaseクラスに定義し、各単例クラスがそれを継承することができるかどうか.単例クラスには初期化オブジェクトが重要な特性があり,baseクラスは自分のオブジェクトしか初期化できず,サブクラスのオブジェクトを初期化できないのか,まだ問題がある.
この時は汎類の思想を使う必要がある.コードを見てみましょう.
template <typename T>
class singleton
{
        static Lock l;
        static T *t;
public:
        static string param;
        static T& instance()
        {
                if (t == NULL)
                {
                        l.lock();
                        if (t == NULL)
                        {
                                t = new T();
                        }
                        l.unlock();
                }
                return *t;
        }
        static T& getInstance()
        {
                return instance();
        }
};
template <typename T>
T *singleton<T>::t=NULL;
template <typename T>
Lock singleton<T>::l;
template <typename T>
string singleton<T>::param="";

class Synonym:public singleton<Synonym>
{
};

class Adcode:public singleton<Adcode>
{
};

class District:public singleton<District>
{
};

3つの単例化クラスを定義しましたSynonym,Adcode,District.コードは多くなく、簡潔です.
最後に、この3つのクラスのインスタンス化を見てみましょう.
Synonym::instance();
Adcode::instance();
District::instance();

//    
Synonym::instance().Print(str);
Adcode::instance().Print(str);
District::instance().Print(str);

//            
Synonym::instance().A(str);
Adcode::instance().B(str);
District::instance().C(str);

参照先:
単例テンプレートクラス(静的単例テンプレートクラス)は、もう一つの設計があり、素晴らしいです.
template <typename T>
class ssingleton
{
protected:
        struct object_creator
        {
                object_creator() { ssingleton<T>::instance(); }
                inline void do_nothing() const { }
        };
        static object_creator create_object;
        ssingleton(){};
public:
        typedef T object_type;
        static object_type & instance()
        {
                static object_type obj;
                create_object.do_nothing();
                return obj;
        }
        static object_type& getInstance()
        {
                return instance();
        }
};

template <typename T>
typename ssingleton<T>::object_creator ssingleton<T>::create_object;

連想は後で続きます...
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
douban.com/note/356749278/douban.com/note/356749293/douban.com/note/356749305/douban.com/note/356749318/douban.com/note/356749326/douban.com/note/356749334/douban.com/note/356749341/douban.com/note/356749354/douban.com/note/356749363/douban.com/note/356749384/douban.com/note/356749468/douban.com/note/356749484/douban.com/note/356749503/douban.com/note/356749523/douban.com/note/356749556/douban.com/note/356749593/douban.com/note/356749611/douban.com/note/356749646/douban.com/note/356749666/douban.com/note/356749695/douban.com/note/356749817/douban.com/note/356749830/douban.com/note/356749853/douban.com/note/356749867/douban.com/note/356749883/douban.com/note/356749927/douban.com/note/356749967/douban.com/note/356749984/douban.com/note/356750045/douban.com/note/356750069/douban.com/note/356750191/douban.com/note/356750216/douban.com/note/356750230/douban.com/note/356750262/douban.com/note/356750287/douban.com/note/356750304/douban.com/note/356750311/douban.com/note/356750324/douban.com/note/356750344/douban.com/note/356750386/douban.com/note/356750438/douban.com/note/356750453/douban.com/note/356750485/douban.com/note/356750504/douban.com/note/356750536/douban.com/note/356750557/douban.com/note/356750561/douban.com/note/356750584/douban.com/note/356750596/douban.com/note/356750606/douban.com/note/356750682/douban.com/note/356750713/douban.com/note/356750731/douban.com/note/356750769/douban.com/note/356750770/douban.com/note/356750784/douban.com/note/356750828/douban.com/note/356750839/douban.com/note/356750848/douban.com/note/356750859/douban.com/note/356750933/douban.com/note/356750952/douban.com/note/356750980/douban.com/note/356751001/douban.com/note/356751031/douban.com/note/356751052/douban.com/note/356751064/douban.com/note/356751072/douban.com/note/356751087/douban.com/note/356751100/douban.com/note/356751172/douban.com/note/356751203/douban.com/note/356751225/douban.com/note/356751240/douban.com/note/356751263/douban.com/note/356751284/douban.com/note/356751295/douban.com/note/356751303/douban.com/note/356751315/douban.com/note/356751325/douban.com/note/356751359/douban.com/note/356751373/douban.com/note/356751383/douban.com/note/356751392/douban.com/note/356751402/douban.com/note/356751416/douban.com/note/356751428/douban.com/note/356751451/douban.com/note/356751476/douban.com/note/356751511/douban.com/note/356751564/douban.com/note/356751572/douban.com/note/356751588/douban.com/note/356751594/douban.com/note/356751615/douban.com/note/356751649/douban.com/note/356751689/douban.com/note/356751725/douban.com/note/356751747/douban.com/note/356751778/douban.com/note/356751843/douban.com/note/356751850/douban.com/note/356751861/douban.com/note/356751871/douban.com/note/356751889/douban.com/note/356751896/douban.com/note/356751909/douban.com/note/356751943/douban.com/note/356751964/douban.com/note/356751999/