最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++實(shí)現(xiàn)單例模式的自動(dòng)釋放

 更新時(shí)間:2021年09月13日 11:49:27   作者:帶著你的名字  
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)單例模式的自動(dòng)釋放,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

單例模式是為了確保某個(gè)類只能創(chuàng)建一個(gè)對(duì)象而設(shè)計(jì)的。當(dāng)一個(gè)程序的某個(gè)類型只允許有一個(gè)實(shí)例的時(shí)候使用。

一般采用動(dòng)態(tài)分配的方式來生成單例對(duì)象,這個(gè)時(shí)候C++程序員就需要考慮內(nèi)存回收的問題了,所以為了避免在使用單例模式時(shí)忘記回收資源而造成內(nèi)存泄漏的問題,在實(shí)現(xiàn)單例模式的時(shí)候就使其可以自動(dòng)被回收。

不帶自動(dòng)釋放的單例模式的實(shí)現(xiàn)與銷毀

我們先來復(fù)習(xí)一下沒有自動(dòng)回收機(jī)制的單例模式的實(shí)現(xiàn)和銷毀。

單例模式的實(shí)現(xiàn):

  • 將構(gòu)造函數(shù)私有化
  • 在類中定義一個(gè)靜態(tài)的指向本類型的指針變量
  • 定義一個(gè)返回值為該類的指針的靜態(tài)成員函數(shù),在類的外部調(diào)用該函數(shù),生成單例對(duì)象。

單例模式的銷毀:

不能在析構(gòu)函數(shù)中釋放那個(gè)指向本類型的指針變量
需要用靜態(tài)的成員函數(shù)回收指向本類型的指針變量,然后在類的外部調(diào)用該成員函數(shù)來銷毀該單例對(duì)象。

單例模式的自動(dòng)釋放

主要思想是,利用C++棧對(duì)象消亡是會(huì)自動(dòng)回收的特點(diǎn),來自動(dòng)回收分配在堆上的單例對(duì)象,可以通過四種方法:友元類、內(nèi)部類+靜態(tài)數(shù)據(jù)成員、atexit()函數(shù)、pthread_once()+atexit()來實(shí)現(xiàn)

廢話不多說,直接上代碼。

1.借助友元類

//利用友元類,實(shí)現(xiàn)單例模式的自動(dòng)釋放

#include <stdio.h>
#include <iostream>

using std::cout;
using std::endl;
using std::cin;

class AutoRelease;

class Singleton{
    //單例模式的類
public:
    static Singleton *getInstance();//返回單例指針

private:
    friend class AutoRelease;
    Singleton();  //構(gòu)造函數(shù)和析構(gòu)函數(shù)都得是private
    ~Singleton();
    static Singleton *_pInstance;
};

Singleton *Singleton::getInstance(){
    if(_pInstance == nullptr){
        _pInstance = new Singleton();
    }
    return _pInstance;
}

Singleton::Singleton()
{
    cout << "Singleton()" << endl;
}

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

class AutoRelease{
    //用來實(shí)現(xiàn)單例的自動(dòng)釋放的類
    //應(yīng)該保存在棧上,程序結(jié)束時(shí)自動(dòng)回收單例的資源
public:
    AutoRelease(){
        cout << "AutoRelease()" << endl;
    }
    ~AutoRelease(){
        cout << "~AutoRelease()" << endl;
        if(Singleton::_pInstance == nullptr){
            return;
        }
        delete Singleton::_pInstance;
        Singleton::_pInstance = nullptr;
    }
};

Singleton *Singleton::_pInstance = nullptr;  //飽漢模式

int main()
{
    Singleton *s1 = Singleton::getInstance();
    Singleton *s2 = Singleton::getInstance();
    AutoRelease at;
    printf("s1 = %p\n", s1);
    printf("s2 = %p\n", s2);
    s1 = nullptr;
    s2 = nullptr;
    return 0;
}

2.借助內(nèi)部類和靜態(tài)數(shù)據(jù)成員

//利用內(nèi)部類,實(shí)現(xiàn)單例模式的自動(dòng)釋放

#include <stdio.h>
#include <iostream>

using std::cout;
using std::endl;
using std::cin;

class Singleton{
    //單例模式的類
public:
    static Singleton *getInstance();//返回單例指針

private:
    friend class AutoRelease;
    Singleton();  //構(gòu)造函數(shù)和析構(gòu)函數(shù)都得是private
    ~Singleton();
    static Singleton *_pInstance;

private:
    //應(yīng)該設(shè)計(jì)為私有類,避免類外的其他成員使用
    class AutoRelease{
        //用來實(shí)現(xiàn)單例的自動(dòng)釋放的內(nèi)部類
        //應(yīng)該保存在棧上,程序結(jié)束時(shí)自動(dòng)回收單例的資源
    public:
        AutoRelease(){
            cout << "AutoRelease()" << endl;
        }
        ~AutoRelease(){
            cout << "~AutoRelease()" << endl;
            if(Singleton::_pInstance == nullptr){
                return;
            }
            delete Singleton::_pInstance;
            Singleton::_pInstance = nullptr;
        }
    };

private:
    static AutoRelease _at;  //由于AutoRelease是private,所以對(duì)象應(yīng)該放在靜態(tài)區(qū)
};

Singleton *Singleton::getInstance(){
    if(_pInstance == nullptr){
        _pInstance = new Singleton();
    }
    return _pInstance;
}

Singleton::Singleton()
{
    cout << "Singleton()" << endl;
}

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


/* Singleton *Singleton::_pInstance = nullptr;  //飽漢模式 */
//飽漢模式多線程時(shí)不安全,需要使用餓漢模式,在程序跑起來前就生成單例對(duì)象
Singleton *Singleton::_pInstance = Singleton::getInstance();//餓漢模式
Singleton::AutoRelease Singleton::_at;

int main()
{
    Singleton *s1 = Singleton::getInstance();
    Singleton *s2 = Singleton::getInstance();
    printf("s1 = %p\n", s1);
    printf("s2 = %p\n", s2);
    s1 = nullptr;
    s2 = nullptr;
    return 0;
}

3.借助atexit()函數(shù)

//利用atexit函數(shù),實(shí)現(xiàn)單例模式的自動(dòng)釋放

#include <stdio.h>
#include <iostream>

using std::cout;
using std::endl;
using std::cin;

class Singleton{
    //單例模式的類
public:
    static Singleton *getInstance();//返回單例指針
    static void destroy();

private:
    friend class AutoRelease;
    Singleton();  //構(gòu)造函數(shù)和析構(gòu)函數(shù)都得是private
    ~Singleton();
    static Singleton *_pInstance;
};

Singleton *Singleton::getInstance(){
    if(_pInstance == nullptr){
        _pInstance = new Singleton();
        //注冊(cè)destroy函數(shù),在進(jìn)程結(jié)束的時(shí)候執(zhí)行,從而自動(dòng)回收單例
        atexit(Singleton::destroy);
    }
    return _pInstance;
}

void Singleton::destroy(){
    if(Singleton::_pInstance == nullptr){
        return;
    }
    delete Singleton::_pInstance;
    Singleton::_pInstance = nullptr;
}

Singleton::Singleton()
{
    cout << "Singleton()" << endl;
}

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

//為了保證多線程情況下的安全性,使用餓漢模式
Singleton *Singleton::_pInstance = Singleton::getInstance();  //餓漢模式

int main()
{
    Singleton *s1 = Singleton::getInstance();
    Singleton *s2 = Singleton::getInstance();
    printf("s1 = %p\n", s1);
    printf("s2 = %p\n", s2);
    s1 = nullptr;
    s2 = nullptr;
    return 0;
}

4.借助pthread_once和atexit函數(shù)

//利用pthread_once和atexit函數(shù),實(shí)現(xiàn)單例模式的自動(dòng)釋放

#include <stdio.h>
#include <iostream>

using std::cout;
using std::endl;
using std::cin;

class Singleton{
    //單例模式的類
public:
    static void init();
    static Singleton *getInstance();//返回單例指針
    static void destroy();

private:
    friend class AutoRelease;
    Singleton();  //構(gòu)造函數(shù)和析構(gòu)函數(shù)都得是private
    ~Singleton();
    static pthread_once_t _once;
    static Singleton *_pInstance;
};

void Singleton::init(){
    //初始化單例,注冊(cè)回收函數(shù)
    if(_pInstance == nullptr){
        _pInstance = new Singleton();
        atexit(Singleton::destroy);
    }
}

Singleton *Singleton::getInstance(){
    //執(zhí)行pthread_once,保證在多線程的情況下創(chuàng)建單例對(duì)象的安全性
    pthread_once(&_once, init);

    return _pInstance;
}

void Singleton::destroy(){
    if(Singleton::_pInstance == nullptr){
        return;
    }
    delete Singleton::_pInstance;
    Singleton::_pInstance = nullptr;
}

Singleton::Singleton()
{
    cout << "Singleton()" << endl;
}

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

//由于已經(jīng)使用了pthread_once來保證安全性,所以使用飽漢模式即可
Singleton *Singleton::_pInstance = nullptr;
/* Singleton *Singleton::_pInstance = Singleton::getInstance();  //餓漢模式 */
pthread_once_t Singleton::_once = PTHREAD_ONCE_INIT;

int main()
{
    Singleton *s1 = Singleton::getInstance();
    Singleton *s2 = Singleton::getInstance();
    printf("s1 = %p\n", s1);
    printf("s2 = %p\n", s2);
    s1 = nullptr;
    s2 = nullptr;
    return 0;
}

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 基于C語言模擬實(shí)現(xiàn)人生重開模擬器游戲

    基于C語言模擬實(shí)現(xiàn)人生重開模擬器游戲

    人生重開模擬器是前段時(shí)間非?;鸬囊粋€(gè)小游戲,所以本文我們將一起學(xué)習(xí)使用c語言寫一個(gè)簡(jiǎn)易版的人生重開模擬器,感興趣的小伙伴可以了解下
    2024-02-02
  • C語言植物大戰(zhàn)數(shù)據(jù)結(jié)構(gòu)二叉樹堆

    C語言植物大戰(zhàn)數(shù)據(jù)結(jié)構(gòu)二叉樹堆

    這篇文章主要為大家介紹了C語言植物大戰(zhàn)數(shù)據(jù)結(jié)構(gòu)二叉樹堆的圖文示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • 如何使用C++獲取指定的重載函數(shù)地址

    如何使用C++獲取指定的重載函數(shù)地址

    重載函數(shù)是完全不同的幾個(gè)函數(shù),有不同的函數(shù)地址,下面這篇文章主要給大家介紹了關(guān)于如何使用C++獲取指定的重載函數(shù)地址的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-06-06
  • C語言對(duì)于volatile與gcc優(yōu)化的探究

    C語言對(duì)于volatile與gcc優(yōu)化的探究

    這篇文章主要介紹了C語言對(duì)于volatile與gcc優(yōu)化的探究,volatile是一個(gè)特征修飾符(type specifier) volatile的作用是作為指令關(guān)鍵字,確保本條指令不會(huì)因編譯器的優(yōu)化而省略,且要求每次直接讀值。這是百度百科的介紹,那編譯器是具體是怎么優(yōu)化的呢
    2023-02-02
  • C++命令行解析包gflags的使用教程

    C++命令行解析包gflags的使用教程

    這篇文章主要給大家介紹了關(guān)于C++命令行解析包gflags的使用教程,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • 將字符串str1復(fù)制為字符串str2的三種解決方法

    將字符串str1復(fù)制為字符串str2的三種解決方法

    以下是對(duì)將字符串str1復(fù)制為字符串str2的三種解決方法進(jìn)行了詳細(xì)的介紹,需要的朋友可以過來參考下,希望對(duì)大家有所幫助
    2013-10-10
  • C++紅黑樹應(yīng)用之手搓set和map

    C++紅黑樹應(yīng)用之手搓set和map

    這篇文章主要為大家詳細(xì)介紹了如何使用紅黑樹封裝set和map,且必須保證兩種數(shù)據(jù)結(jié)構(gòu)復(fù)用同一棵紅黑樹,且滿足set和map的性質(zhì),set的value不可被改變,而map的value可以被改變,需要的可以參考一下
    2023-03-03
  • 詳解C語言中的自定義類型

    詳解C語言中的自定義類型

    這篇文章主要為大家詳細(xì)介紹了C語言中的四大自定義類型(結(jié)構(gòu)體、位段、枚舉和聯(lián)合)的相關(guān)知識(shí),文中的示例代碼簡(jiǎn)潔易懂,需要的可以參考一下
    2023-07-07
  • C++輸入輸出操作符重載的深入分析

    C++輸入輸出操作符重載的深入分析

    本篇文章是對(duì)C++輸入輸出操作符重載進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • C/C++實(shí)現(xiàn)字符串模糊匹配

    C/C++實(shí)現(xiàn)字符串模糊匹配

    本文分別給大家介紹了2個(gè)C++在Linux平臺(tái)和windows平臺(tái)下實(shí)現(xiàn)字符串模糊匹配的方法,基本的核心思想都是一樣的,均是使用fnmatch函數(shù),有需要的小伙伴可以參考下。
    2016-04-04

最新評(píng)論

远安县| 碌曲县| 股票| 安丘市| 夏津县| 城口县| 达日县| 昌吉市| 科技| 贞丰县| 文登市| 醴陵市| 云霄县| 威宁| 墨竹工卡县| 自治县| 县级市| 定远县| 曲周县| 浦县| 屯昌县| 平江县| 泰安市| 姜堰市| 文山县| 凌海市| 隆安县| 如东县| 文化| 桑植县| 融水| 高密市| 西城区| 新乡县| 迁安市| 彭泽县| 察雅县| 晋江市| 江永县| 日土县| 赤城县|