設計模式之 再說單例模式

來源:互聯網
上載者:User

昨天寫了個單例模式,當時感覺有個問題:

new出來的對象一直沒有釋放!這不是記憶體泄露嗎?


後來就看了別人的代碼,java中是沒有的,因為不需要。又看了一份c++的,也沒有。我就想,可能不需要吧,在程式運行期間,最多隻有一個instance,不會耗盡記憶體的,最多O(1)的記憶體。


可是今天怎麼考慮覺得這種解釋太牽強了!如果對象很大呢?如果有很多類的單例instance呢?

於是又繼續查,發現很多人都沒有寫解構函式,但是有些還是有的。

所以,解構函式還是需要的。一個完美的代碼是不能有潛在bug的。


既然需要一個解構函式,那麼在哪裡調用呢?在程式結束後手動調用?顯然這樣不好。因為我們不知道什麼時候不再需要這個對象。


再網上看到別人一個巧妙的解決方案:

使用一個內部類負責析構。感覺有點像代理模式了?

因為任何靜態對象在程式運行期間都存在,生命期結束後都會被收回。所以可以讓這個靜態對象析構的時候析構這個單例對象。


其實還有另外一個問題,很大的bug:

雖然定義了protected的建構函式,但是仍然不能保證只有一個instance,因為還有拷貝建構函式和賦值建構函式,調用的話編譯器會合成。。。


改進後的代碼:

#include <iostream>using namespace std;class   Singleton{protected:    Singleton() {cout<<"con  of Singleton"<<endl;}    ~Singleton(){cout<<"dcon of Singleton"<<endl;}    Singleton(const Singleton& s);///只定義,不實現public:    static  Singleton * getInstance()    {        if(_instance==0)        {            _instance = new Singleton();        }        return _instance;    }    ///other class functions...    void    show()    {        cout<<"This is a Singleton !"<<endl;    }private:    static  Singleton * _instance;    ///other class members ...    class   Proxy    {    public:        ~Proxy()        {            if(_instance!=0)            {                delete _instance;                _instance = 0;            }        }    };    static Proxy pt;};///靜態成員的初始化Singleton*          Singleton::_instance = 0;//new Singleton();Singleton::Proxy    Singleton::pt;int main(){    Singleton *s=Singleton::getInstance();    s->show();    Singleton *a=Singleton::getInstance();    a->show();    cout<<(a == s)<<endl;    //Singleton b; ///compile error!    //Singleton c(*s);///compile error!    //Singleton d=*a;///compile error!    return 0;}

暫時應該是沒問題了。

考慮最佳化,如果在程式中大量調用getInstance(),除了第一次判斷成功外,其他情況下這段代碼

        if(_instance==0)        {            _instance = new Singleton();        }

顯得很多餘!

可以在初始化時就建立一個對象:

Singleton*          Singleton::_instance = new Singleton();

然後把上面的if 程式碼片段刪除,就可以了。


如果不是返回指標,使用引用即可:

#include <iostream>using namespace std;class   Singleton{protected:    Singleton() {cout<<"con  of Singleton"<<endl;}    ~Singleton(){cout<<"dcon of Singleton"<<endl;}    Singleton(const Singleton& s);///只定義,不實現public:    static  Singleton & getInstance()    {        return _instance;    }    ///other class functions...    void    show()    {        cout<<"This is a Singleton !"<<endl;    }private:    static  Singleton & _instance;    ///other class members ...    class   Proxy    {    public:        ~Proxy()        {            _instance.~Singleton();        }    };    static Proxy pt;};///靜態成員的初始化Singleton&          Singleton::_instance = *(new Singleton());Singleton::Proxy    Singleton::pt;int main(){    Singleton &s=Singleton::getInstance();    s.show();    Singleton &a=Singleton::getInstance();    a.show();    cout<<(&s==&a)<<endl;    return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.