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

談?wù)凜++中的單例

 更新時間:2020年09月11日 14:46:56   作者:tlanyan  
這篇文章主要介紹了C++中單例的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)c++,感興趣的朋友可以了解下

寫C++的時候用到單例,于是很自然的寫出如下的代碼:

namespace tlanyan {
  class Foo {
  private:
    static Foo* _instance;
    Foo() {}
    // other members

  public:
    static Foo* getInstance() {
      if (_instance == NULL) {
        _instance = new Foo();
      }
      return _instance;
    }
    ~Foo() {
      // clean codes
    }
    // other members and codes
  };
  Foo* Foo::_instance = NULL;
}

代碼的本意:靜態(tài)成員函數(shù)getInstance獲取單例指針,并且在析構(gòu)函數(shù)中做一些收尾工作。

運(yùn)行代碼后發(fā)現(xiàn)析構(gòu)函數(shù)死活不執(zhí)行,難道一個單例模式都能寫錯?反復(fù)確認(rèn),沒發(fā)現(xiàn)問題所在,于是上萬能的StackOverflow上找原因。正好有伙計有同樣的疑惑,有哥們給出了一個可行的方案。根據(jù)其答案修改代碼如下:

namespace tlanyan {
  class Foo {
  private:
    Foo() {}
    // other members

  public:
    static Foo& getInstance() {
      static Foo _instance;
      return _instance;
    }
    ~Foo() {
      // clean codes
    }
    // other members and codes
  };
}

對比前一段代碼,主要改動是移除了靜態(tài)指針成員,改用函數(shù)內(nèi)的靜態(tài)成員。由于_instance是函數(shù)內(nèi)的靜態(tài)成員,在首次調(diào)用時被初始化(感謝無參構(gòu)造函數(shù)),之后調(diào)用將略過初始化而執(zhí)行后續(xù)代碼;函數(shù)返回實例的引用,故而每次調(diào)用得到的是同一個對象,達(dá)到了單例的目的;程序執(zhí)行結(jié)束后,實例的析構(gòu)函數(shù)被自動調(diào)用,析構(gòu)函數(shù)中的代碼正確執(zhí)行。

問題解決了,但什么原因造成第一段單例代碼的析構(gòu)函數(shù)不執(zhí)行呢?

這是由于C++持有對象的方式造成的(或者說C++允許程序員手動控制內(nèi)存引起)。Java/PHP等帶有回收機(jī)制的語言,持有對象的方式是通過指針,程序員申請對象后會自動分配內(nèi)存,系統(tǒng)負(fù)責(zé)跟蹤和回收無用的對象和存在。C++允許開發(fā)人員以變量的方式持有對象,例如:Foo foo [= Foo(args)]。變量初始化后獲得對象的引用,離開作用域后,系統(tǒng)銷毀執(zhí)行棧,對象自動被析構(gòu)。C++也可以以指針的形式獲得對象的引用: Foo* foo = new Foo(args)。這種方式分配的對象,需要開發(fā)人員手動管理。如果不執(zhí)行delete,對象和分配的內(nèi)存將一直存在,直到程序退出后,才由操作系統(tǒng)回收。如下代碼可說明這點:

namespace tlanyan {
  void foo() {
    Foo foo;  // 聲明變量,編譯器會自動初始化變量
    Foo* ptr = new Foo();  // 聲明對象指針,同時為對象開辟內(nèi)存
    // awesome codes
    return;    // 離開作用域, foo對象將被自動析構(gòu);如果之前沒有調(diào)用過delete ptr, ptr指向的對象將一直存在;如果delete ptr,析構(gòu)函數(shù)將被執(zhí)行。也可以將ptr指向的對象賦值給外層作用域的指針,此時有多個指針指向同一個變量
  }
}

從上面的代碼可以看出,對象沒有引用計數(shù)的情況下,編譯器和系統(tǒng)不敢隨便回收new出來的對象內(nèi)存:多個指針指向同一個對象,delete了對象可能會導(dǎo)致其他代碼崩潰;釋放內(nèi)存后,其他指針再delete會多次delete同一塊內(nèi)存,引發(fā)不可預(yù)知風(fēng)險。

綜上,指針單例析構(gòu)函數(shù)沒有被調(diào)用的原因是: 自己new的對象,需要自己delete,別指望別人幫你正確調(diào)用析構(gòu)函數(shù)。

問題的解決方案有以下幾種:

  1. 同StackOverflow上回答,改用變量方式持有單例對象。程序運(yùn)行結(jié)束前會銷毀所有變量,變量的析構(gòu)函數(shù)將被正確調(diào)用;
  2. 在main函數(shù)退出前delete單例。例如增加一個destroy的靜態(tài)成員函數(shù),將指針指向的對象銷毀;
  3. 使用auto_ptr/unique_ptr等智能指針。

如有其它解決方案,歡迎交流指正!

以上就是談?wù)凜++中的單例的詳細(xì)內(nèi)容,更多關(guān)于c++ 單例的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 淺談C++中virtual的三種用法

    淺談C++中virtual的三種用法

    這篇文章主要介紹了淺談C++中virtual的三種用法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • C++模板的特化超詳細(xì)精講

    C++模板的特化超詳細(xì)精講

    最近我學(xué)習(xí)了C++中的模板相關(guān)知識,模板是泛型編程的基礎(chǔ),十分重要。所以特意整理出來一篇文章供我們一起復(fù)習(xí)和學(xué)習(xí)
    2022-08-08
  • C語言實現(xiàn)串的順序存儲表示與基本操作

    C語言實現(xiàn)串的順序存儲表示與基本操作

    這篇文章主要為大家詳細(xì)介紹了C語言實現(xiàn)串的順序存儲表示與基本操作,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • C++中變量進(jìn)行初始化的3種方法

    C++中變量進(jìn)行初始化的3種方法

    本文主要介紹了C++中變量進(jìn)行初始化的3種方法,包括用"=",構(gòu)造函數(shù)初始化以及統(tǒng)一初始化這三種方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-02-02
  • C++數(shù)據(jù)結(jié)構(gòu)之AVL樹的實現(xiàn)

    C++數(shù)據(jù)結(jié)構(gòu)之AVL樹的實現(xiàn)

    AVL樹是高度平衡的而二叉樹,它的特點是AVL樹中任何節(jié)點的兩個子樹的高度最大差別為1,本文主要給大家介紹了C++如何實現(xiàn)AVL樹,需要的朋友可以參考下
    2022-06-06
  • C語言求矩陣的各列元素之和的代碼示例

    C語言求矩陣的各列元素之和的代碼示例

    這篇文章主要介紹了C語言求矩陣的各列元素之和的代碼示例,這也是經(jīng)常作為競賽和計算機(jī)專業(yè)考試的基礎(chǔ)練習(xí)出現(xiàn)的題目,需要的朋友可以參考下
    2016-07-07
  • C++中this指針理解及作用

    C++中this指針理解及作用

    這篇文章主要介紹了C++中this指針理解及作用,文章通過舉例展開相關(guān)詳細(xì)內(nèi)容,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-05-05
  • 深入探討:宏、內(nèi)聯(lián)函數(shù)與普通函數(shù)的區(qū)別

    深入探討:宏、內(nèi)聯(lián)函數(shù)與普通函數(shù)的區(qū)別

    本篇文章是對宏、內(nèi)聯(lián)函數(shù)與普通函數(shù)的區(qū)別進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • C 語言程序結(jié)構(gòu)示例解析

    C 語言程序結(jié)構(gòu)示例解析

    本文主要講解C 語言程序結(jié)構(gòu),這里提供簡單的示例來講解C 語言程序的結(jié)構(gòu),有利于剛剛學(xué)習(xí)C 語言的同學(xué)理解程序結(jié)構(gòu)
    2016-08-08
  • C++實現(xiàn)簡單通訊錄管理系統(tǒng)

    C++實現(xiàn)簡單通訊錄管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C++實現(xiàn)簡單通訊錄管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02

最新評論

汉沽区| 若尔盖县| 繁昌县| 嘉峪关市| 丽江市| 古交市| 岳西县| 碌曲县| 大竹县| 治多县| 库尔勒市| 乌拉特中旗| 会同县| 昭通市| 芷江| 澎湖县| 廊坊市| 肇源县| 塔河县| 南岸区| 德庆县| 淮滨县| 东辽县| 泰州市| 巍山| 防城港市| 潮安县| 三门峡市| 临朐县| 大名县| 威远县| 八宿县| 会东县| 崇义县| 同心县| 高邮市| 聂荣县| 怀安县| 诸暨市| SHOW| 大理市|