国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

C++之單例的幾種寫法

開發
單例可以說是眾多設計模式中最常用的了,同時單例設計模式也是一個老生常談的問題,這是因為寫一個單例卻是很簡單,但是想要寫好一個單例卻比較難。

單例可以說是眾多設計模式中最常用的了,同時單例設計模式也是一個老生常談的問題,這是因為寫一個單例卻是很簡單,但是想要寫好一個單例卻比較難。

首先我們先來理一下在C++中實現單例最基本的幾個步驟:

  • 私有化構造函數、拷貝構造函數、賦值運算符等;
  • 確保線程安全;
  • static靜態變量只初始化一次;

單例的幾種模式

1.最簡單的餓漢模式

#include <iostream>

class Singleton {
private:
    // 聲明
    static Singleton* instance;
    int a{0};
    Singleton() {
        std::cout << "Singleton 構造函數" << std::endl;
    }
    Singleton(const Singleton& temp) {
        std::cout << "Singleton 拷貝構造函數" << std::endl;
    }
    Singleton& operator = (const Singleton& temp){
        return *instance;
    }

public:
    static Singleton* getInstance() {
        return instance;
    }

    void addA(){
        a++;
    }

    void printA(){
        std::cout << "printA:" << a << std::endl;
    }
};

// 類靜態變量要在類內聲明,類外定義
Singleton *Singleton::instance = new Singleton;

int main() {
    Singleton* singleton = Singleton::getInstance();
    singleton->addA();
    singleton->printA();
    return 0;
}

這種寫法常用,但是也藏了一些隱患,比如如果使用者自作聰明在通過函數getInstance獲取到了單例指針,使用完畢后調用delete刪除了指針那怎么辦? 請問作為"資深"的復制粘貼工程師你知道怎么避免這種情況嗎?

一把情況下我們如果不希望開發者調用delete刪除指針,可以直接重載delete函數,并且將其設置偉私有方法,或者在C++11以上我們直接使用delete關鍵字將delete函數禁用掉。

上面的代碼例子是指針形式的單例,當然你也可以試試非指針式的單例書寫,其實更推薦非指針式的單例。

2.加鎖的餓漢模式

#include <iostream>
#include <mutex>

class Singleton {
private:
    int a{0};
    // 聲明
    static std::mutex mtx;
    static Singleton* instance;
    Singleton(){

    }
    Singleton(const Singleton& temp) {
        std::cout << "Singleton 拷貝構造函數" << std::endl;
    }
    Singleton& operator=(const Singleton& temp){
        return *instance;
    }
public:
    static Singleton* getInstance() {
        // 鎖、雙重判斷
        if(nullptr == instance){
            mtx.lock();
            if (nullptr == instance) {
                instance = new Singleton();
            }
            mtx.unlock();
        }
        return instance;
    }

    void addA(){
        a++;
    }

    void printA(){
        std::cout << "printA:" << a << std::endl;
    }
};

// 需要定義
std::mutex Singleton::mtx;
Singleton *Singleton::instance{nullptr};

int main() {
    Singleton* singleton = Singleton::getInstance();
    singleton->addA();
    singleton->printA();
    return 0;
}

想用懶加載模式,同時為了保證線程安全,以上代碼是很多童鞋會寫出的示例代碼,然而在C++上述代碼卻并不能一定保證正確。

這是因為程序在執行的過程中,出于效率的考量,兩個(在當前線程中)沒有依賴的指令可能會調換順序執行也就是 CPU 動態調度。對于 CPU 來說,這已經是幾十年的老技術了, 這里就不多說了。

因此以上這個鎖加雙重判斷的懶漢模式既繁瑣又不安全,并不推薦。

3.C++11之后新特性std::call_once的模式

在單例的實現中,我們實際上是希望實現「執行且只執行一次」的語義。這在 C++11 之后,標準庫實際已經提供了這樣的實現。 那就是std::once_flag和std::call_once。它們內部利用互斥量和條件變量組合,實現了「執行且只執行一次」這樣的語義。

下面我們看看使用std::once_flag和std::call_once實現的單例代碼實例:

#include <iostream>
#include <mutex>

class Singleton {
private:
    int a{0};
    // 聲明
    static std::once_flag flag;
    static Singleton* instance;
    Singleton(){
        std::cout << "Singleton 構造函數" << std::endl;
    }
    Singleton(const Singleton& temp) {
        std::cout << "Singleton 拷貝構造函數" << std::endl;
    }
    Singleton& operator=(const Singleton& temp){
        return *instance;
    }
public:
    static Singleton* getInstance() {
        std::call_once(flag, [&]() -> void {
            instance = new Singleton;
        });
        return instance;
    }

    void addA(){
        a++;
    }

    void printA(){
        std::cout << "printA:" << a << std::endl;
    }
};

// 需要定義
std::once_flag Singleton::flag;
Singleton *Singleton::instance{nullptr};

int main() {
    Singleton* singleton = Singleton::getInstance();
    singleton->addA();
    singleton->printA();
    Singleton::getInstance()->addA();
    Singleton::getInstance()->printA();
    return 0;
}

實例代碼運行結果:

需要注意的是,所有的 std::once_flag 內部共享了同一對互斥量和條件變量。因此當存在很多 std::call_once 的時候,性能會有所下降。 但是從另外一個角度想想如果一個程序中存在很多的std::call_once,那么這個程序本身就設計得很不合理,這種情況更應該從程序設計的源頭上避免。

4.函數內static變量的模式

在 C++11 之后,C++標準保證函數靜態成員的初始化是線程安全的,對其讀寫則不保證線程安全。既然如此,那么我在直接在函數內部使用static 修飾一個單例變量不就好了么?

精簡一下代碼如下:

#include <iostream>

class Singleton {
private:
    int a{0};
    Singleton(){
        std::cout << "Singleton 構造函數" << std::endl;
    }
    Singleton(const Singleton& temp) {
        std::cout << "Singleton 拷貝構造函數" << std::endl;
    }
    Singleton& operator=(const Singleton& temp){
        return *this;
    }
public:
    static Singleton* getInstance() {
        static Singleton instance;
        return &instance;
    }

    void addA(){
        a++;
    }

    void printA(){
        std::cout << "printA:" << a << std::endl;
    }
};

int main() {
    Singleton* singleton = Singleton::getInstance();
    singleton->addA();
    singleton->printA();
    Singleton::getInstance()->addA();
    Singleton::getInstance()->printA();
    return 0;
}

以上代碼實現的單例即是線程安全,同時也是懶加載的,這就是在C++11之后,Effective C++最推薦的單例模式寫法。

模版形式的單例

實現一個類模板,其模板參數是希望由單例管理的類的名字,并提供 getInstance 之類的靜態接口。這種做法的好處是希望被單例管理的類,可以自由編寫,而無需繼承基類;并且在需要的時候,可以隨時脫去單例外衣。

#include <iostream>

template <typename T>
struct Singleton {
    static T* getInstance() {
        static T ins;
        return &ins;
    }
};

class A{
private:
    int a{0};
    A(const A& tmp){
        std::cout << "A拷貝構造函數" << std::endl;
    }
    A& operator=(const A& tmp){
        std::cout << "A賦值運算符" << std::endl;
        return *this;
    }

public:
    A(){
        std::cout << "A構造函數" << std::endl;
    }
    void addA(){
        a++;
    }

    void printA(){
        std::cout << "printA:" << a << std::endl;
    }
};

int main() {
    A* singleton = Singleton<A>::getInstance();
    singleton->addA();
    singleton->printA();
    A* singleton1 = Singleton<A>::getInstance();
    singleton1->addA();
    singleton1->printA();
    return 0;
}

由上面的代碼可以看出,單例管理就交給了模版Singleton去控制了,類A本身就不知乎嚴格控制自己是否是單例了,這種實現就比較的靈活,如果你想使用單例的類A就搭配Singleton的模版進行使用即可, 如果你想使用非單例的類A就像正常那樣使用即可。

責任編輯:趙寧寧 來源: 思想覺悟
相關推薦

2022-05-23 07:35:15

單例模式懶漢模式靜態內部類

2015-09-06 11:07:52

C++設計模式單例模式

2010-02-05 17:00:06

C++單例模式

2024-12-03 16:49:58

2010-02-03 09:43:16

C++單例模式

2022-08-10 11:02:56

Python單例模式

2010-01-27 10:45:21

C++單例模式

2023-03-21 15:21:52

開發程序設計static

2012-02-02 10:21:05

單鏈表nexthead

2021-09-07 10:44:35

異步單例模式

2025-08-18 02:11:00

2010-02-06 11:13:11

C++ makefil

2010-01-22 14:46:25

C++語言

2016-03-28 10:23:11

Android設計單例

2021-06-10 09:00:33

單例模式數據庫

2013-03-26 10:35:47

Objective-C單例實現

2011-07-15 00:47:13

C++多態

2010-02-06 14:12:54

C++繼承方式

2011-07-14 17:45:06

CC++

2022-06-07 08:55:04

Golang單例模式語言
點贊
收藏

51CTO技術棧公眾號

亚洲国产成人av网| 久久精品123| 色综合夜色一区| 4438x成人网全国最大| 日韩午夜激情免费电影| 多野结衣av一区| 亚洲欧美日韩高清| 日本伊人久久| 久久久水蜜桃| 久久伊人蜜桃av一区二区| 超碰97人人射妻| 欧美日韩国产综合一区二区| 日韩欧美主播在线| 国产毛片av在线| 在线电影欧美日韩一区二区私密| 国产黄色在线观看| 久久久精品视频成人| 激情五月色综合国产精品| 狠狠色综合网站久久久久久久| 色呦呦在线看| 精品成人一区二区三区四区| 97品白浆高清久久久久久| 国产成+人+综合+亚洲欧美丁香花| 四季av一区二区凹凸精品| 狠狠干视频网站| 一本一本久久a久久精品综合麻豆| 中韩乱幕日产无线码一区| 国产精品va在线| 成人晚上爱看视频| av五月婷婷| 国产精品影视网| 精品日本一区二区三区| 成人午夜短视频| 午夜激情视频在线观看| 91精品国产自产在线老师啪| 国产精品亚洲四区在线观看 | 日韩免费成人| 人妻少妇精品久久| 日韩经典第一页| 免费人成网站在线观看欧美高清| 91成人福利在线观看| 欧美一区二区私人影院日本| av在线首页| 日本精品免费一区二区三区| 成人免费va视频| 国产精品麻豆一区二区三区| 欧美最猛性xxxxx免费| 亚洲国产精品久久久天堂 | 午夜激情一区| 亚洲一区二区三区成人在线视频精品| 羞羞答答一区二区| 日本成人免费| 日本精品视频网站| 亚洲一区二区三区四区在线| a成人v在线| 黄色激情在线视频| 日韩久久精品电影| 91香蕉视频黄| 欧美成人精品午夜一区二区| 只有这里有精品| 日韩精品在线一区二区| 精品一区二区三区在线播放| 亚洲高清视频一区| 日韩一级视频免费观看在线| 日韩专区在线视频| 极品视频在线| 蜜桃传媒九九九| 国产精品二区三区| 亚洲品质视频自拍网| 99免费精品在线观看| 欧美97人人模人人爽人人喊视频| 四季av一区二区| 国产精品嫩草影院一区二区| 日韩影视高清在线观看| 四虎精品在永久在线观看| 国产精品一区免费观看| 在线亚洲午夜片av大片| 欧美高清在线精品一区| 亚洲性感美女99在线| 亚洲日本va| caopen在线视频| 日本wwwwww| 亚洲日本无吗高清不卡| 欧美在线中文字幕| 日韩无一区二区| 男女男精品视频网| 日韩精品永久网址| 电影在线观看一区| 蜜桃成人在线视频| 日韩在线观看a| 亚洲qvod图片区电影| 日韩精品高清在线| 亚洲一区二区三区国产| 不卡一区二区中文字幕| 久久午夜视频| 亚洲精品国产偷自在线观看| 国产资源在线观看入口av| 中文字幕97| 日韩精品免费播放| 欧美最新大片在线看| 91色视频在线| 日日夜夜精品视频天天综合网| 国产99久久| 麻豆一区二区| 97成人超碰| 激情开心成人网| 成人黄色网址| 免费大片在线观看www| 欧美日韩国产中文字幕在线| 视频一区二区综合| 国产午夜精品在线| 国产精品久久亚洲7777| 青青草成人在线| 国产亚洲欧美视频| 91麻豆国产在线观看| 在线观看日韩av电影| 99久久.com| 综合久久亚洲| 亚洲麻豆av| 亚洲国产日韩欧美在线| 国产精品啊v在线| 欧美69wwwcom| 悠悠资源网久久精品| 精品国产一区二区三区久久久蜜臀| www国产精品| 日韩久久电影| 一区二区三区四区日韩| 香蕉视频一区二区三区| 亚洲8888| 日本国产在线| 8888四色奇米在线观看| 金瓶狂野欧美性猛交xxxx| 2024最新电影免费在线观看| 经典三级一区二区| 625成人欧美午夜电影| 性欧美video高清bbw| 黄色免费网站在线观看| 看电影就来5566av视频在线播放| 波多野结衣中文在线| 国产美女视频一区二区| 99视频精品全国免费| 国内精品视频在线观看| 日本不卡视频在线观看| 国产成人av资源| 成人久久18免费网站麻豆| 成人在线视频一区二区| www视频在线观看| 中日韩美女免费视频网站在线观看 | 久久亚洲国产精品| 国产精品自在线| 天天做天天爱天天高潮| 国产精品视频黄色| 91福利国产在线观看菠萝蜜| 高清一区二区| 欧美日韩一区二区高清| 成人黄页在线观看| 日韩欧美一二三区| 国产精品手机播放| 日韩中文字幕免费在线| 在线国产情侣| 免费一区二区三区视频导航| 精一区二区三区| 欧美一区在线视频| 国产不卡精品视男人的天堂| 国产成人亚洲综合无码| 欧美18hd| 欧美一区2区| 久久网站热最新地址| 亚洲欧美在线第一页| 国产精品精品一区二区三区午夜版| 丰满的少妇愉情hd高清果冻传媒| 国产视频在线播放| 在线视频亚洲| 亚洲在线视频网站| 日本久久久久久久久久久| 手机福利在线视频| 午夜羞羞小视频在线观看| 一本久久知道综合久久| 亚洲成人av中文| 91久久国产自产拍夜夜嗨| 天堂资源av| 欧美日韩 国产精品| 欧美精品久久一区| 免费看国产精品一二区视频| 色佬视频在线观看| 日韩av网站在线免费观看| 久久久高清一区二区三区| 日韩精品一区二区视频| 日韩亚洲视频在线| 男人av在线播放| 国产亚洲精品7777| 91网站黄www| 久久成年人视频| 成人午夜剧场免费观看完整版| 国内精品视频在线观看| 亚洲午夜久久久久| 精品国产aⅴ麻豆| crdy在线观看欧美| 亚洲欧美一区二区三区极速播放 | 欧美另类视频|