單例模板工廠

簡述

單例,顧名思義,就是一個程序中,只能存在一個這樣的實例。所以要實現單例必須

  • 私有化構造函數,禁止外部創建新的對象
  • 私有化析構函數,防止資源不正確釋放
  • 私有化拷貝構造函數,禁止拷貝出新的對象
  • 私有化賦值運算符,禁止通過賦值創建出新的對象
  • 提供獲取實例的方法
  • 提供銷燬實例的方法

簡單實現

#include <iostream>

class Singleton
{
    Singleton()
    {
        std::cout  << "creator object" << std::endl;
    }

    ~Singleton()
    {
        std::cout  << "destroy object" << std::endl;
    }

public:
    static Singleton *Instance()
    {
        if(!self) {
            self = new Singleton;
        }
        return self;
    }

    void destroy()
    {
        if(self) {
            delete self;
            self = NULL;
        }
    }

    void dosomething()
    {
        std::cout  << "do something" << std::endl;
    }

private:
    static Singleton *self;

    Singleton(const Singleton &);
    Singleton &operator = (const Singleton &);
};

Singleton *Singleton::self = NULL;

單例實現好了,來應用

int main(int , char *[])
{
    Singleton *obj = Singleton::Instance();
    obj->dosomething();
    obj->destroy();
    return 0;
}

輸出

creator object
do something
destroy object

無異常,但每次都需要在程序結束前手動刪除,可能會不小心漏了, 所以需要增加一個自動釋放資源的類。

Singleton 中增加嵌套類GC用於垃圾回收,由於嵌套類GC 使用了Singleton 中的私有靜態成員變量,所以GC也必須私有化,防止在類外創建

class GC
{
public:
	GC() { }
    ~GC()
    {
        if (self) {
            delete self;
            self = NULL;
        }
    }
};

修改獲取實例的方法

    static Singleton *Instance()
    {
        if(!self) {
            static GC gc;
            self = new Singleton;
        }
        return self;
    }

使用

int main(int , char *[])
{
    Singleton*obj = Singleton::Instance();
    obj->dosomething();

    return 0;
}

輸出

creator object
do something
destroy object

這樣程序關閉時,就會自動釋放單例資源。

完整代碼

#include <iostream>

class Singleton
{
    Singleton()
    {
        std::cout  << "creator object" << std::endl;
    }

    ~Singleton()
    {
        std::cout  << "destroy object" << std::endl;
    }

public:
    static Singleton *Instance()
    {
        if(!self) {
            static GC gc;
            self = new Singleton;
        }
        return self;
    }

    void destroy()
    {
        if(self) {
            delete self;
            self = NULL;
        }
    }

    void dosomething()
    {
        std::cout  << "do something" << std::endl;
    }

private:
    static Singleton *self;

    Singleton(const Singleton &);
    Singleton &operator = (const Singleton &);

    class GC
    {
    public:
        GC() { }
        ~GC()
        {
            if (self) {
                delete self;
                self = NULL;
            }
        }
    };
};

Singleton *Singleton::self = NULL;
int main(int , char *[])
{
    Singleton *obj = Singleton::Instance();
    obj->dosomething();

    return 0;
}

單例工廠

有時候一個程序中存在大量單例,每個單例都需要重新實現這些方法,有沒有方法可以把這些重複的部分複用起來呢?

創建工廠

template <typename T>
class Factory
{
    static T *singleton;
public:
    static T *Instance()
    {
        if(!singleton) {
            static GC gc;
            singleton = new T;
        }
        return singleton;
    }

private:
    Factory() {} //禁止構造,禁止繼承

    class GC
    {
    public:
        GC() { }
        ~GC()
        {
            if (singleton) {
                delete singleton;
                singleton = NULL;
            }
        }
    };
};

template <class T>
T *Factory<T>::singleton = NULL;

創建需要單例化的類

class Object
{
    friend class Factory<Object>;

    Object()
    {
        std::cout  << "creator object" << std::endl;
    }

    ~Object()
    {
        std::cout  << "destroy object" << std::endl;
    }

    Object(const Object &);
    Object &operator = (const Object &);

public:
    void dosomething()
    {
        std::cout  << "do something" << std::endl;
    }
};

typedef Factory<Object> Singleton;

本類私有化了構造函數和析構函數,聲明瞭友元類Factory<Object>, 並將其重命名爲 Singleton

下面看使用方法

int main(int , char *[])
{
    Singleton::Instance()->dosomething();

    return 0;
}

輸出

creator object
do something
destroy object

當然,模板單例還可以使用繼承的方法,繼承模板,實現模板單例,但這裏我將模板的構造函數私有化了,使其不可被繼承。並且,本例程 非線程安全 ,需要線程安全的可自行加鎖。

想要使用繼承的方法實現模板單例,網上很多,這裏就不再過多贅述了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章