當前位置:首頁 » 操作系統 » sharedptr源碼

sharedptr源碼

發布時間: 2022-10-05 11:58:22

① 不想編譯boost庫如何引用boost庫的頭文件啊

需定義相應的宏,如你不希望使用date_time庫的動態鏈接庫,你可以定義BOOST_DATE_TIME_SOURCE和BOOST_DATE_TIME_NO_LIB來使用切入源碼的方式。不同庫需要定義不同的宏

② vs2008關於C++的shared_ptr

shared_ptr需要VS2008 SP1以上才自帶有,頭文件為#include <memory>,或者使用boost庫(boost::shared_ptr),頭文件為#include <boost/shared_ptr.hpp>

vs2008 error C2039: 「shared_ptr」: 不是「std::tr1」的成員

vs2008創建的c++項目中用到了std::tr1::shared_ptr,
編譯時報錯:error C2039: 「shared_ptr」: 不是「std::tr1」的成員。
原因:未安裝vs2008 SP1
VS90sp1-KB945140-CHS.exe:
http://www.microsoft.com/downloads/zh-cn/details.aspx?FamilyID=FBEE1648-7106-44A7-9649-6D9F6D58056E
VS2008SP1CHSX1512981.iso:
http://www.microsoft.com/downloads/zh-cn/details.aspx?FamilyID=27673C47-B3B5-4C67-BD99-84E525B5CE61
若 不安裝vs2008 SP1,也可使用Boost的實現boost::shared_ptr

③ c++智能指針有哪些

在C++編程中,智能指針絕對是很強大的用法,boost庫里把這些指針用的出神入化,它可以簡化程序員寫代碼的復雜度,不用去考慮代碼分支路徑導致的遺漏delete語法,也無須擔心冗餘delete導致的double free問題。但是,便利性也要求程序猿熟悉各種指針的用法,避免誤用,反而帶來其他問題。下面簡要列下常用的智能指針,及其用法:
1.scoped_ptr:這是最常用的智能指針,當你new一塊內存後,把內存地址交給scoped_ptr管理,這樣就不用顯式調用delete了,當離開作用於後,該內存會被自動釋放,如
int* p = new int;
scoped_ptr<int> scoped_int_ptr(p);
注意:無須再delete p;這樣會double free。另外一個重要的點是:scoped_ptr不允許傳遞指針,即他的拷貝構造和賦值函數都是private的,不允許調用,所以你不能寫如下代碼
scoped_ptr<int> scoped_int_ptr2 = scoped_int_ptr; // 不允許
2.auto_ptr:它和scoped_ptr用法基本是一致的,但是它允許指針傳遞,拷貝構造和賦值函數允許調用,故名思意,當發生賦值時,原對象的指針會轉移給新對象,這時原對象的指針就為NULL了,不能再調用。所以,對指針要把握好,使用應謹慎。
3.shared_ptr:scoped_ptr一樣包裝了new操作符在堆上分配的動態對象,但它實現的是引用計數型的智能指針 ,可以被自由地拷貝和賦值,在任意的地方共享它,當沒有代碼使用(引用計數為0)它時才刪除被包裝的動態分配的對象。但是,shared_ptr注意不要有循環引用,否則會出現內存泄漏。例如:A和B對象互相引用,它們的引用計數都是1,當出了作用域之後,二者不能自動釋放,出現了內存泄漏。
4.weak_ptr:是一種智能指針,它對被 std::shared_ptr 管理的對象存在非擁有性(「弱」)引用。在訪問所引用的對象前必須先轉換為 std::shared_ptr。
std::weak_ptr 用來表達臨時所有權的概念:當某個對象只有存在時才需要被訪問,而且隨時可能被他人刪除時,可以使用std::weak_ptr 來跟蹤該對象。需要獲得臨時所有權時,則將其轉換為 std::shared_ptr,此時如果原來的std::shared_ptr 被銷毀,則該對象的生命期將被延長至這個臨時的 std::shared_ptr 同樣被銷毀為止。
此外,std::weak_ptr 還可以用來避免 std::shared_ptr 的循環引用。

④ c++關於shared_ptr的問題

shared_ptr<char> sc(new char[10]);
shared_ptr<char> sc(new char[10] {'a', 'b', 'c', 'd'});

⑤ C11新特性之智能指針

程序都是在堆上存儲動態分配對象,而它的生存期是由程序來控制的。這就意味著當動態對象不再使用的時候,我們需要顯式的將它銷毀。

c98提出了一個智能指針auto_ptr為了避免人們使用指針時忘記釋放內存。但是因為auto_ptr的總總缺點,使人們在開發過程碰到了各種坑,所以才有了c11新的三個智能指針。

移動語義是c11提出的,c11最大的特性就是擁有了移動而不是拷貝對象的能力,這就大幅度的提升了性能。
為了讓自定義類型的對象也支持移動操作,我們為它定義了 移動構造函數 移動賦值運算符
移動構造函數是對資源進行竊取而不是拷貝。它的第一個參數是該類類型的右值引用,移動構造函數除了完成資源移動外,還必須保證移動之後的原對象處於 有效的、可析構 的狀態(將原對象值賦值給新對象,然後把原對象屬性值置空,特別是指針成員置空!那麼此時原對象就是處於可析構的安全狀態)。

看了memory里的部分源碼,發現有一個在c11之前沒有出現過的關鍵字explict

有了explict關鍵字的限定,防止類構造函數進行隱式轉換

它禁止拷貝語義,但是是通過移動語義(什麼是移動語義?上面有解答)來實現的。它「唯一」擁有它所指的對象。
從下面的unique_ptr的構造函數就可以發現它是禁止拷貝語義的。

但是如果想要切換指針的控制權,可以使用下面的移動構造函數來進行控制權的轉化,這里用到forward轉發(上一節可以知道forward轉發可以返回該參數本來對應的類型的引用),其實這里就是把右值對象移動給左值,並且把右值對象置空

了解了前面的auto_ptr和unique_ptr,再來理解shared_ptr非常容易。
與前面兩者不同的是,shared_ptr允許多個指針指向相同對象,前兩者在切換控制權時,會將前面的清除,而shared_ptr不會。

當刪除其中一個智能指針時,另外兩個並不會受到變化。因為此時內存中存在著引用計數,每添加一個shared_ptr,引用計數+1,每次調用析構函數,引用計數-1。直到引用計數減為0,才會釋放該塊內存。
auto_ptr和unique_ptr都可以通過move函數轉換成shared_ptr類型
當使用shared_ptr時,最需要注意的就是 避免循環引用 ,它會造成堆內存無法正常釋放,出現內存泄露。如何解決這個問題呢,這時候就要用到weak_ptr的lock()鎖

我們最好在使用weak_ptr訪問對象時,使用lock()函數,它可以檢測weak_ptr訪問的對象是否存在,如果存在,返回一個內存中的shared_ptr對象,不存在,返回一個nullptr的shared_ptr

當雙向鏈表的前驅指針和後繼指針使用了shared_pre,如下

由於使用了shared_pre,一塊內存空間有兩個對象進行管理,而無法使引用計數為0,那麼編譯器就無法自動釋放內存。

使用弱引用,弱引用並不會修改對象的引用計數,也就是弱引用並不會對對象的內存進行管理。但是它能檢測到引用對象是否被釋放,避免了內存泄露。weak_pre就是弱引用。

⑥ 請教C++語句:shared_ptr<T>static_pointer_cast(const shared_ptr<U>&r)

很簡單,這是一個函數。
shared_ptr<T>是返回值
函數名稱:static_pointer_cast;
參數const shared_ptr<U>&r'
就這么簡單。

補充:那不叫取址。。那叫引用。
你難道這點c++基礎都沒有?那你還敢看Boost源碼?

⑦ 如何把普通指針轉為智能指針share

最近項目中使用boost庫的智能指針,感覺智能指針還是蠻強大的,在此貼出自己學習過程中編寫的測試代碼,以供其他想了解boost智能指針的朋友參考,有講得不正確之處歡迎指出討論。當然,使用boost智能指針首先要編譯boost庫,具體方法可以網上查詢,在此不再贅述。

智能指針能夠使C++的開發簡單化,主要是它能夠自動管理內存的釋放,而且能夠做更多的事情,即使用智能指針,則可以再代碼中new了之後不用delete,智能指針自己會幫助你管理內存資源的釋放。

Boost庫的智能指針有很多種,下面通過示例代碼來說明其中share_ptr的使用方法。

// test.cpp : Defines the entry point for the console application.
#include "stdafx.h"
#include <iostream>
#include <boost/shared_ptr.hpp>
#include <vector>

/** 測試類 */
class CTest
{
public:

/** 構造函數 */
CTest(int m)
{
m_member = m;

/** 申請空間 */
m_pname = new char[2];
}
/** 析構函數 */
~CTest()
{
delete m_pname;
}

/** 成員函數 */
int getMember()
{
return m_member;
}

private:

/** 數據成員 */
int m_member;
char * m_pname;

};

int _tmain(int argc, _TCHAR* argv[])
{

/** 示例代碼【1】 */

/** boost::shared_ptr智能指針含有一個引用計數器 */
/** 引用指針計數器記錄有多少個引用指針指向同一個對象,如果最後一個引用指針被銷毀的時候,那麼就銷毀對象本身。 */

/** 使用智能指針創建一個對象 */
/** 注意: 智能指針不支持直接 new 例如: boost::shared_ptr<CTest> pTemp = new CTest(2) 是錯誤的 */
boost::shared_ptr<CTest> pTemp(new CTest(10));

/** 創建一個新的智能指針也指向新創建的CTest對象 */
/** 智能指針支持等號操作 */
boost::shared_ptr<CTest> pSecond = pTemp;

/** 通過智能指針訪問該對象 */
std::cout << pTemp->getMember() << std::endl;

/** 讓第一個智能指針為空,不再指向該對象,注意,智能指針不能使用 pTemp = NULL */
pTemp.reset();

/** 讓第二個智能指針也為空,這時該CTest對象已經沒有智能指針指向它了,會自動析構 */
pSecond.reset();

/** 示例代碼【2】 */

/** 將一個普通的指針轉換為智能指針 */

/** 創建一個普通的指針,new一個對象 */
CTest * pATest = new CTest(100);
/** 轉換為智能指針 */
boost::shared_ptr<CTest> pShareTest(pATest);

/** 智能指針會自動管理創建的CTest對象,不允許再進行delete,否則程序會掛掉 */
delete pATest;

/** 讓智能指針為空,則對象會被自動析構 */
pShareTest.reset();

/** 示例代碼【3】 */

/** 創建一個容器存放智能指針 */
/** 這里需要注意: 兩個「 > 」 不要寫到一起了,否則會產生 >> 運算符重載 */
std::vector<boost::shared_ptr<CTest> > vec;

/** 創建一個臨時的CTest對象,存放到上面的容器 */

{

⑧ 如何:創建和使用shared_ptr實例

make_shared 是異常安全的。它使用同一調用分配的內存控制塊和該資源從而減少構造開銷。如果不使用 make_shared,則必須使用顯式新的表達式創建對象,然後將其傳遞給 shared_ptr 構造函數之前。下面的示例演示各種方式與新的對象同時聲明和初始化 shared_ptr。VBC#C++F#JScriptPowerShell No code example is currently available or this language may not be supported. 下面的示例演示如何聲明和初始化採用對象共享所有權另一 shared_ptr已分配的 shared_ptr 實例。假定,sp2 是初始化的 shared_ptr。VBC#C++F#JScriptPowerShell No code example is currently available or this language may not be supported. shared_ptr 也很有用在標准模板庫 (STL) 容器,當您使用"復制元素的演算法時。可以包裝在 shared_ptr的元素,然後將其復制到完全理解的其他容器基礎內存有效,只要不需要且不再。下面的示例在矢量演示如何使用在 shared_ptr 實例的 replace__if 演算法。VBC#C++F#JScriptPowerShell No code example is currently available or this language may not be supported. 可以使用 dynamic_pointer_cast、static_pointer_cast和const_pointer_cast 轉換shared_ptr。這些功能類似於 dynamic_cast、static_cast和const_cast 運算符。下面的示例演示如何測試每個元素的派生類型在基類 shared_ptr 矢量的,然後復制元素並顯示有關它們的信息。VBC#C++F#JScriptPowerShell No code example is currently available or this language may not be supported. 可以通過以下方式通過 shared_ptr 到另一個函數:通過shared_ptr 值。此調用復制構造函數,會遞增引用計數,並使被調用方所有者。具有此操作的少量系統開銷,可能是有意義的根據經歷 shared_ptr 對象通過。使用此選項,當代碼協定 (提示或顯式) 時在調用方和被調用方之間要求被調用方是所有者。通過shared_ptr 引用或常數引用。在這種情況下,引用計數不增加,因此,被調用方可以訪問指針,只要調用方不超出范圍。或者,則被調用方可以決定創建基於引用的 shared_ptr 從而形成一個共享的所有者。使用此選項,當調用方不了解被調用方時,或者,如果必須通過 shared_ptr 和若要出於性能原因時避免復制操作。通過基礎指針或引用為基礎對象。這使得被調用方使用對象,但是,不使共享所有權或擴展生存期。如果被調用方創建原始指針的 shared_ptr,新 shared_ptr 與原來的是獨立的和不控制此類基礎資源。使用此選項,則在調用方和被調用方之間的協定的清單指定時調用方保留 shared_ptr 生存期的所有權。當您決定如何通過 shared_ptr,確定被調用方是否必須共享這種基礎資源的所有權。「所有者」是可以使這種基礎資源運行的對象或函數,只要它需要它。如果調用方必須確保則被調用方可以擴展指針的生存期在其 (函數) 的生存期以外的,請使用第一個選項。如果您不關心被調用方是否擴展生存期,則可以通過引用並允許被調用方復制它。如果必須允許幫助器到基礎指針的函數訪問,因此,您了解 helper 函數將使用指針和返回,在被調用函數返回以前,則該函數不必共享基礎指針的所有權。它必須對調用方的 shared_ptr的生存期內指針。在這種情況下,通過 shared_ptr 引用或通過原始的指針或引用為基礎對象是安全的。通過此方式提供一個小的性能改進,並且還有助於表示您編程的用途。

⑨ shared_ptr實現和線程安全分析

使用該智能指針(或者其他兩種)需要導入頭文件 #include <memory>

除此之外還可以對 shared_ptr 賦值,通過重寫 operator= 實現。 需要注意 ,對於 p1=p2 (均為智能指針)這種, p2 所指對象由於被 p1 指向,所以該引用計數會加一, p1 原本指向的資源的引用計數會減一。這也會引出下面關於 shared_ptr 指針的 線程安全 問題。

運行結果如下:

這里實現的還有一些問題,因為 shared_ptr 源碼中關於引用計數是 原子操作 ,不需要考慮資源使用沖突的問題,可以在自己實現的時候加鎖。

首先什麼是線程安全?
簡單來說就是 多個線程操作一個共享數據,都能按照預期的行為進行,無論多個線程的運行次序如何交織。

對於 shared_ptr ,其內部有兩個變數,引用計數和真正的對象類型指針。其中引用計數是原子操作,所以 對於 shared_ptr 的讀操作是線程安全的。

但是對於 shared_ptr 中賦值如 ptr1 = ptr2 ,需要兩個步驟, 1、 ptr1 的內部對象指針 Obj1 替換成 ptr2 內部對象 Obj2 指針;2、 ptr1 的對於 Obj1 的引用計數緩存 Obj2 的引用計數。

這兩步並不是原子的,如果一個線程需要對 shared_ptr 進行賦值操作 ptr1 = ptr2 ,剛完成第一步,就切換到其他線程又對ptr2進行操作,如 ptr2 = ptr3 ,就有可能造成析構了引用計數。而繼續之前線程的第二步,就會出錯。

總之:對於 shared_ptr 的讀操作是線程安全的。
對於 shared_ptr 讀寫操作不是線程安全的,需要加鎖。

tips:為什麼 shared_ptr 的引用計數能夠同步到不同的指針中?

有人回答可能使用的是static變數,這是不可能的,因為一個類中只有一個靜態變數,只能記錄對於一個對象的引用次數,這在包含兩個 shared_ptr 以上的程序中是不可行的。
個人認為是引用計數是用指針實現的,指向一個記錄引用次數的對象。

熱點內容
python基礎語言 發布:2024-04-27 11:54:40 瀏覽:83
ioshttp伺服器搭建 發布:2024-04-27 11:40:26 瀏覽:912
忘記密碼如何強制刷機vivo 發布:2024-04-27 11:28:40 瀏覽:384
c語言讀取指定行 發布:2024-04-27 11:28:30 瀏覽:51
c語言中a10什麼意思 發布:2024-04-27 10:45:43 瀏覽:58
物聯網中ftp是什麼意思 發布:2024-04-27 10:41:17 瀏覽:986
銀行密碼保護在哪裡 發布:2024-04-27 10:25:23 瀏覽:189
tomcat源碼導入eclipse 發布:2024-04-27 10:25:15 瀏覽:194
android的api 發布:2024-04-27 10:23:39 瀏覽:683
官式訪問 發布:2024-04-27 10:04:00 瀏覽:522