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

深度剖析C++對象池自動回收技術(shù)實現(xiàn)

 更新時間:2019年01月17日 10:51:33   作者:修語講編程  
今天小編就為大家分享一篇關(guān)于深度剖析C++對象池自動回收技術(shù)實現(xiàn),小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧

對象池可以顯著提高性能,如果一個對象的創(chuàng)建非常耗時或非常昂貴,頻繁去創(chuàng)建的話會非常低效。對象池通過對象復(fù)用的方式來避免重復(fù)創(chuàng)建對象,它會事先創(chuàng)建一定數(shù)量的對象放到池中,當(dāng)用戶需要創(chuàng)建對象的時候,直接從對象池中獲取即可,用完對象之后再放回到對象池中,以便復(fù)用。這種方式避免了重復(fù)創(chuàng)建耗時或耗資源的大對象,大幅提高了程序性能。本文將探討對象池的技術(shù)特性以及源碼實現(xiàn)。

對象池類圖

ObjectPool:管理對象實例的pool。

Client:使用者。

適用性:

類的實例可重用。

類的實例化過程開銷較大。

類的實例化的頻率較高。

效果:

節(jié)省了創(chuàng)建類實例的開銷。

節(jié)省了創(chuàng)建類實例的時間。

存儲空間隨著對象的增多而增大。

問題

目前縱觀主流語言的實現(xiàn)方式無外乎3個步驟:

初始創(chuàng)建一定數(shù)量的對象池(也允許從外面添加對象)。

從對象池中取對象來使用。

用完之后返回對象池。

一般情況下這樣是OK的,可能存在的問題是在第三步,有兩個問題:

不方便,每次都需要顯式回收對象。

忘記將對象放回對象池,造成資源浪費。

改進動機

解決顯式回收的問題,實現(xiàn)自動回收,省心省力。改進之后的對象池?zé)o須提供release方法,對象會自動回收,改進之后的類圖如下。

技術(shù)內(nèi)幕

借助c++11智能指針,因為智能指針可以自定義刪除器,在智能指針釋放的時候會調(diào)用刪除器,在刪除器中我們將用完的對象重新放回對象池。思路比較簡單,但實現(xiàn)的時候需要考慮兩個問題:

什么時候定義刪除器?以及用shared_ptr還是unique_ptr?下面我們一起來看一下: 

1. 什么時候定義刪除器

自定義刪除器只做一件事,就是將對象重新放入對象池。如果對象池初始化的時候就自定義刪除器的話,刪除器中的邏輯是將對象放回對象池,放回的時候無法再定義一個這樣的刪除器,所以這種做法行不通。需要注意,回收的對象只能是默認刪除器的。除了前述原因之外,另外一個原因是對象池釋放的時候需要釋放所有的智能指針,釋放的時候如果存在自定義刪除器將會導(dǎo)致對象無法刪除。只有在get的時候定義刪除器才行,但是初始創(chuàng)建或加入的智能指針是默認刪除器,所以我們需要把智能指針的默認刪除器改為自定義刪除器。

2 .用shared_ptr還是unique_ptr

因為我們需要把智能指針的默認刪除器改為自定義刪除器,用shared_ptr會很不方便,因為你無法直接將shared_ptr的刪除器修改為自定義刪除器,雖然你可以通過重新創(chuàng)建一個新對象,把原對象拷貝過來的做法來實現(xiàn),但是這樣做效率比較低。而unique_ptr由于是獨占語義,提供了一種簡便的方法方法可以實現(xiàn)修改刪除器,所以用unique_ptr是最適合的。

2.實現(xiàn)源碼

#pragma once
#include <memory>
#include <vector>
#include <functional>
template <class T>
class SimpleObjectPool
{
public:
  using DeleterType = std::function<void(T*)>;
  void add(std::unique_ptr<T> t)
  {
    pool_.push_back(std::move(t));
  }
  std::unique_ptr<T, DeleterType> get()
  {
    if (pool_.empty())
    {
      throw std::logic_error("no more object");
    }
    //every time add custom deleter for default unique_ptr
    std::unique_ptr<T, DeleterType> ptr(pool_.back().release(), [this](T* t)
    {
      pool_.push_back(std::unique_ptr<T>(t));
    });
    pool_.pop_back();
    return std::move(ptr);
  }
  bool empty() const
  {
    return pool_.empty();
  }
  size_t size() const
  {
    return pool_.size();
  }
private:
  std::vector<std::unique_ptr<T>> pool_;
};
//test code
void test_object_pool()
{
  SimpleObjectPool<A> p;
  p.add(std::unique_ptr<A>(new A()));
  p.add(std::unique_ptr<A>(new A()));
  {
    auto t = p.get();
    p.get();
  }
  {
    p.get();
    p.get();
  }
  std::cout << p.size() << std::endl;
}

如果你堅持用shared_ptr,那么回收的時候你需要這樣寫:

std::shared_ptr<T> get()
{
if (pool_.empty())
{
throw std::logic_error("no more object");
}
std::shared_ptr<T> ptr = pool_.back();
auto p = std::shared_ptr<T>(new T(std::move(*ptr.get())), [this](T* t)
{
pool_.push_back(std::shared_ptr<T>(t));
});
//std::unique_ptr<T, DeleterType> ptr(pool_.back().release(), [this](T* t)
//{
// pool_.push_back(std::unique_ptr<T>(t));
//});
pool_.pop_back();
return p;
}

這種方式需要每次都創(chuàng)建一個新對象,并且拷貝原來的對象,是一種比較低效的做法。代碼僅僅是為了展示如何實現(xiàn)自動回收對象,沒有考慮線程安全、對象池擴容策略等細節(jié),源碼鏈接:object_pool

小結(jié)

凡是需要自動回收的場景下都可以使用這種方式:在獲取對象的時候?qū)⒛J刪除器改為自定義刪除器,確保它可以回收。注意,回收的智能指針使用的是默認刪除器,可以確保對象池釋放時能正常釋放對象。同時也將獲取對象和釋放對象時,對象的控制權(quán)完全分離。其他的一些應(yīng)用場景:多例模式,無需手動釋放,自動回收。

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,謝謝大家對腳本之家的支持。如果你想了解更多相關(guān)內(nèi)容請查看下面相關(guān)鏈接

相關(guān)文章

  • C語言實現(xiàn)鏈表貪吃蛇

    C語言實現(xiàn)鏈表貪吃蛇

    這篇文章主要為大家詳細介紹了C語言實現(xiàn)鏈表貪吃蛇,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-06-06
  • C++?STL容器與函數(shù)謂詞示例分析講解

    C++?STL容器與函數(shù)謂詞示例分析講解

    這篇文章主要介紹了C++?STL容器與函數(shù)謂詞示例,STL是“Standard?Template?Library”的縮寫,中文譯為“標(biāo)準(zhǔn)模板庫”。STL是C++標(biāo)準(zhǔn)庫的一部分,不用單獨安裝
    2022-11-11
  • C語言入門篇--四大常量(字面,const修飾,宏,枚舉)及標(biāo)識符

    C語言入門篇--四大常量(字面,const修飾,宏,枚舉)及標(biāo)識符

    本篇文章是c語言基礎(chǔ)篇,主要講述一下常量,常量即不可被直接修改的量(const修飾的常變量可間接修改,后續(xù)文章會繼續(xù)說明)請大家持續(xù)關(guān)注腳本之家
    2021-08-08
  • C語言中獲取進程識別碼的相關(guān)函數(shù)

    C語言中獲取進程識別碼的相關(guān)函數(shù)

    這篇文章主要介紹了C語言中獲取進程識別碼的相關(guān)函數(shù),分別為getpid()函數(shù)和getppid()函數(shù)的使用,需要的朋友可以參考下
    2015-08-08
  • C++編寫簡易的飛機大戰(zhàn)

    C++編寫簡易的飛機大戰(zhàn)

    一款自己設(shè)計的飛機小游戲,本程序于運行環(huán)境WINDOWS XP系統(tǒng),采用C++語言編寫。游戲具有得分排名榜,而且在游戲完成后可以提交得分到網(wǎng)絡(luò)上的世界排名榜中。
    2015-08-08
  • Qt利用QScroller實現(xiàn)home界面滑動效果

    Qt利用QScroller實現(xiàn)home界面滑動效果

    這篇文章主要為大家詳細介紹了Qt如何利用QScroller實現(xiàn)home界面滑動效果,文中的實現(xiàn)過程講解詳細,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2022-11-11
  • C語言 動態(tài)內(nèi)存分配詳解

    C語言 動態(tài)內(nèi)存分配詳解

    這篇文章主要介紹了C語言 動態(tài)內(nèi)存分配詳解的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • c++利用stl set_difference對車輛進出區(qū)域進行判定

    c++利用stl set_difference對車輛進出區(qū)域進行判定

    這篇文章主要介紹了set_difference,用于求兩個集合的差集,結(jié)果集合中包含所有屬于第一個集合但不屬于第二個集合的元素,需要的朋友可以參考下
    2017-03-03
  • c++11&14-STL要點匯總

    c++11&14-STL要點匯總

    這篇文章主要介紹了c++11&14中的STL要點,文中代碼簡單易懂,方便大家更好的學(xué)習(xí)參考,感興趣的朋友可以了解下
    2020-06-06
  • C語言使用鏈表實現(xiàn)學(xué)生籍貫管理系統(tǒng)

    C語言使用鏈表實現(xiàn)學(xué)生籍貫管理系統(tǒng)

    這篇文章主要為大家詳細介紹了C語言使用鏈表實現(xiàn)學(xué)生籍貫管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02

最新評論

文水县| 县级市| 汕尾市| 舞阳县| 德化县| 自治县| 汉寿县| 祁阳县| 长兴县| 繁峙县| 内丘县| 剑阁县| 江源县| 泸水县| 长岛县| 星座| 华宁县| 泰来县| 堆龙德庆县| 治县。| 石嘴山市| 吉首市| 铜梁县| 建湖县| 蒙山县| 昭平县| 卢氏县| 南昌县| 张家港市| 信丰县| 浪卡子县| 玉环县| 苗栗市| 泾阳县| 桓台县| 称多县| 即墨市| 宁化县| 栾城县| 老河口市| 个旧市|