中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當前位置: 首頁 > news >正文

做公司網(wǎng)站搜索引擎優(yōu)化seo專員

做公司網(wǎng)站,搜索引擎優(yōu)化seo專員,哪些網(wǎng)站可以做免費外貿(mào),國外視頻設計網(wǎng)站智能指針 shared_ptrshared_ptr的基本用法使用shared_ptr要注意的問題 unique_ptr獨占的智能指針weak_ptr弱引用的智能指針weak_ptr的基本用法weak_ptr返回this指針weak_ptr解決循環(huán)引用問題 weak_ptr使用注意事項 智能指針 C程序設計中使用堆內(nèi)存是非常頻繁的操作&#xff0…

智能指針 shared_ptrshared_ptr的基本用法使用shared_ptr要注意的問題 unique_ptr獨占的智能指針weak_ptr弱引用的智能指針weak_ptr的基本用法weak_ptr返回this指針weak_ptr解決循環(huán)引用問題 weak_ptr使用注意事項

智能指針

C++程序設計中使用堆內(nèi)存是非常頻繁的操作,堆內(nèi)存的申請和釋放都由程序員自己管理。程序員自己 管理堆內(nèi)存可以提高了程序的效率,但是整體來說堆內(nèi)存的管理是麻煩的,C++11中引入了智能指針的 概念,方便管理堆內(nèi)存。使用普通指針,容易造成堆內(nèi)存泄露(忘記釋放),二次釋放,程序發(fā)生異常 時內(nèi)存泄露等問題等,使用智能指針能更好的管理堆內(nèi)存。

C++里面的四個智能指針: auto_ptr,unique_ptr,shared_ptr, weak_ptr 其中后三個是C++11支持, 并且第一個已經(jīng)被C++11棄用。

shared_ptr

共享的智能指針 std::shared_ptr使用引用計數(shù),每一個shared_ptr的拷貝都指向相同的內(nèi)存。再最后一個shared_ptr析 構(gòu)的時候,內(nèi)存才會被釋放。 shared_ptr共享被管理對象,同一時刻可以有多個shared_ptr擁有對象的所有權(quán),當最后一個 shared_ptr對象銷毀時,被管理對象自動銷毀。 簡單來說,shared_ptr實現(xiàn)包含了兩部分,

  • 一個指向堆上創(chuàng)建的對象的裸指針:raw_ptr

  • 一個指向內(nèi)部隱藏的、共享的管理對象:share_count_object

第一部分沒什么好說的,第二部分是需要關注的重點. use_count:當前這個堆上對象被多少對象引用了,簡單來說就是引用計數(shù)。

shared_ptr的基本用法

  1. 初始化

通過構(gòu)造函數(shù)、std::shared_ptr輔助函數(shù)和reset方法來初始化shared_ptr,代碼如下:

// 智能指針初始化std::shared_ptr<int> p1(new int(1));std::shared_ptr<int> p2 = p1;std::shared_ptr<int> p3;p3.reset(new int(1));if(p3) {cout << "p3 is not null";}

我們應該優(yōu)先使用make_shared來構(gòu)造智能指針,因為他更高效。

auto sp1 = make_shared<int>(100);//相當于shared_ptr<int> sp1(new int(100));

不能將一個原始指針直接賦值給一個智能指針,例如,下面這種方法是錯誤的:

std::shared_ptr<int> p = new int(1);

shared_ptr不能通過“直接將原始這種賦值”來初始化,需要通過構(gòu)造函數(shù)和輔助方法來初始化。 對于一個未初始化的智能指針,可以通過reset方法來初始化,當智能指針有值的時候調(diào)用reset會引起 引用計數(shù)減1。另外智能指針通過重載的bool類型操作符來判斷是否為空。

#include <iostream>#include <memory>using namespace std;void test(shared_ptr<int> sp) {// sp在test里面的作用域cout << "test sp.use_count()" <<sp.use_count() << endl;}int main(){auto sp1 = make_shared<int>(100); // 優(yōu)先使用make_shared來構(gòu)造智能指針//相當于shared_ptr<int> sp2(new int(100));// ?  std::shared_ptr<int> p = new int(1);  // 不能將一個原始指針直接賦值給一個智能指針std::shared_ptr<int> p1;p1.reset(new int(1)); ?// 有參數(shù)就是分配資源std::shared_ptr<int> p2 = p1;// 引用計數(shù)此時應該是2cout << "p2.use_count() = " << p2.use_count()<< endl; ?// 2cout << "p1.use_count() = " << p1.use_count()<< endl; ?// 2p1.reset(); ? // 沒有參數(shù)就是釋放資源cout << "p1.reset()\n";// 引用計數(shù)此時應該是1cout << "p2.use_count()= " << p2.use_count() << endl; ?// 1cout << "p1.use_count() = " << p1.use_count()<< endl; ?// 2if(!p1) { ?// p1是空的cout << "p1 is empty\n";}if(p2) { // p2非空cout << "p2 is not empty\n";}p2.reset();cout << "p2.reset()\n";cout << "p2.use_count()= " << p2.use_count() << endl;if(!p2) {cout << "p2 is empty\n";}shared_ptr<int> sp5(new int(100));test(sp5);cout << "sp5.use_count()" << sp5.use_count() << endl;return 0;}/*p2.use_count() = 2p1.use_count() = 2p1.reset()p2.use_count()= 1p1.use_count() = 0p1 is emptyp2 is not emptyp2.reset()p2.use_count()= 0p2 is emptytest sp.use_count()2sp5.use_count()1*/
  1. 獲取原始指針

當需要獲取原始指針時,可以通過get方法來返回原始指針,代碼如下所示:

std::shared_ptr<int> ptr(new int(1));int *p = ptr.get(); //萬一不小心 delete p;

謹慎使用p.get()的返回值,如果你不知道其危險性則永遠不要調(diào)用get()函數(shù)。?

p.get()的返回值就相當于一個裸指針的值,不合適的使用這個值,上述陷阱的所有錯誤都有可能發(fā)生, 遵守以下幾個約定: 不要保存p.get()的返回值 ,無論是保存為裸指針還是shared_ptr都是錯誤的 保存為裸指針不知什么時候就會變成空懸指針,保存為shared_ptr則產(chǎn)生了獨立指針 不要delete p.get()的返回值 ,會導致對一塊內(nèi)存delete兩次的錯誤

  1. 指定刪除器

如果用shared_ptr管理非new對象或是沒有析構(gòu)函數(shù)的類時,應當為其傳遞合適的刪除器。

#include <iostream>#include <memory>using namespace std;void DeleteIntPtr(int *p) {cout << "call DeleteIntPtr" << endl;delete p;}int main(){std::shared_ptr<int> p(new int(1), DeleteIntPtr);std::shared_ptr<int> p2(new int(1), [](int *p) {cout << "call lambda1 delete p" << endl;delete p;});std::shared_ptr<int> p3(new int[10], [](int *p) {cout << "call lambda2 delete p" << endl;delete [] p; // 數(shù)組刪除});return 0;}/*call lambda2 delete pcall lambda1 delete pcall DeleteIntPtr*/

當p的引用計數(shù)為0時,自動調(diào)用刪除器DeleteIntPtr來釋放對象的內(nèi)存。刪除器可以是一個lambda表達 式,上面的寫法可以改為:

std::shared_ptr<int> p(new int(1), [](int *p) {cout << "call lambda delete p" << endl;delete p;});

當我們用shared_ptr管理動態(tài)數(shù)組時,需要指定刪除器,因為shared_ptr的默認刪除器不支持數(shù)組對 象,代碼如下所示:

std::shared_ptr<int> p3(new int[10], [](int *p) { delete [] p;});
  • 智能指針什么時候需要指定刪除器

在需要 delete 以外的析構(gòu)行為的時候用. 因為 shared_ptr 在引用計數(shù)為 0 后默認調(diào)用 delete ptr; 如果不滿足需求就要提供定制的刪除器.

一些場景:

  • 資源不是 new 出來的(一般也意味著不能 delete), 比如可能是 malloc 出來的

  • 資源是被第三方庫管理的 (第三方提供 資源獲取 和 資源釋放 接口, 那么要么寫一個 wrapper 類要么就提供定制的 deleter)

  • 資源不是 RAII 的, 意味著析構(gòu)函數(shù)不會把資源完全釋放掉...也就是單純 delete 還不夠, 還得做額外的操作比如你的 end_connection 的例子. 雖然我覺得這個是 bad practice

使用shared_ptr要注意的問題

  1. 不要用一個原始指針初始化多個shared_ptr,例如下面錯誤范例:

int *ptr = new int;
shared_ptr<int> p1(ptr);
shared_ptr<int> p2(ptr); // 邏輯錯誤
  1. 不要在函數(shù)實參中創(chuàng)建shared_ptr,對于下面的寫法:

function(shared_ptr<int>(new int), g()); //有缺陷

因為C++的函數(shù)參數(shù)的計算順序在不同的編譯器不同的約定下可能是不一樣的,一般是從右到左,但也 可能從左到右,所以,可能的過程是先new int,然后調(diào)用g(),如果恰好g()發(fā)生異常,而shared_ptr還 沒有創(chuàng)建, 則int內(nèi)存泄漏了,正確的寫法應該是先創(chuàng)建智能指針,代碼如下:

shared_ptr<int> p(new int);
function(p, g());
  • 形參和實參的區(qū)別和聯(lián)系

  1. 形參變量只有在函數(shù)被調(diào)用時才會分配內(nèi)存,調(diào)用結(jié)束后,立刻釋放內(nèi)存,所以形參變量只有在函數(shù)內(nèi)部有效,不能在函數(shù)外部使用。

  2. 實參可以是常量、變量、表達式、函數(shù)等,無論實參是何種類型的數(shù)據(jù),在進行函數(shù)調(diào)用時,它們都必須有確定的值,以便把這些值傳送給形參,所以應該提前用賦值、輸入等辦法使實參獲得確定值。

  3. 實參和形參在數(shù)量上、類型上、順序上必須嚴格一致,否則會發(fā)生“類型不匹配”的錯誤。當然,如果能夠進行自動類型轉(zhuǎn)換,或者進行了強制類型轉(zhuǎn)換,那么實參類型也可以不同于形參類型。

  4. 函數(shù)調(diào)用中發(fā)生的數(shù)據(jù)傳遞是單向的,只能把實參的值傳遞給形參,而不能把形參的值反向地傳遞給實參;換句話說,一旦完成數(shù)據(jù)的傳遞,實參和形參就再也沒有瓜葛了,所以,在函數(shù)調(diào)用過程中,形參的值發(fā)生改變并不會影響實參。

請看下面的例子:

#include <stdio.h>//計算從m加到n的值
int sum(int m, int n) {int i;for (i = m+1; i <= n; ++i) {m += i;}return m;
}int main() {int a, b, total;printf("Input two numbers: ");scanf("%d %d", &a, &b);total = sum(a, b);printf("a=%d, b=%d\n", a, b);printf("total=%d\n", total);return 0;
}
/*
運行結(jié)果:
Input two numbers: 1 100
a=1, b=100
total=5050
*/

在這段代碼中,函數(shù)定義處的 m、n 是形參,函數(shù)調(diào)用處的 a、b 是實參。通過 scanf() 可以讀取用戶輸入的數(shù)據(jù),并賦值給 a、b,在調(diào)用 sum() 函數(shù)時,這份數(shù)據(jù)會傳遞給形參 m、n。

從運行情況看,輸入 a 值為 1,即實參 a 的值為 1,把這個值傳遞給函數(shù) sum() 后,形參 m 的初始值也為 1,在函數(shù)執(zhí)行過程中,形參 m 的值變?yōu)?5050。函數(shù)運行結(jié)束后,輸出實參 a 的值仍為 1,可見實參的值不會隨形參的變化而變化。

  1. 通過shared_from_this()返回this指針。不要將this指針作為shared_ptr返回出來,因為this指針 本質(zhì)上是一個裸指針,因此,這樣可能會導致重復析構(gòu),看下面的例子。

//1-1-shared_from_this
#include <iostream>
#include <memory>using namespace std;class A
{
public:shared_ptr<A>GetSelf(){return shared_ptr<A>(this); // 不要這么做}~A(){cout << "Deconstruction A" << endl;}
};int main()
{shared_ptr<A> sp1(new A);shared_ptr<A> sp2 = sp1->GetSelf();cout << "sp1.use_count() = " << sp1.use_count()<< endl;cout << "sp2.use_count() = " << sp2.use_count()<< endl;return 0;
}/*
sp1.use_count() = 1
sp2.use_count() = 1
Deconstruction A
Deconstruction A
*/

在這個例子中,由于用同一個指針(this)構(gòu)造了兩個智能指針sp1sp2,而他們之間是沒有任何關系 的,在離開作用域之后this將會被構(gòu)造的兩個智能指針各自析構(gòu),導致重復析構(gòu)的錯誤。

正確返回this的shared_ptr的做法是:讓目標類通過std::enable_shared_from_this類,然后使用基類的 成員函數(shù)shared_from_this()來返回this的shared_ptr,如下所示。

//1-1-shared_from_this2
#include <iostream>
#include <memory>using namespace std;class A: public std::enable_shared_from_this<A>
{
public:shared_ptr<A>GetSelf(){return shared_from_this(); //}~A(){cout << "Deconstruction A" << endl;}
};int main()
{// auto spp = make_shared<A>();shared_ptr<A> sp1(new A);shared_ptr<A> sp2 = sp1->GetSelf();  // ok//    shared_ptr<A> sp2;//    {//        shared_ptr<A> sp1(new A);//        sp2 = sp1->GetSelf();  // ok//    }cout << "sp1.use_count() = " << sp1.use_count()<< endl;cout << "sp2.use_count() = " << sp2.use_count()<< endl;return 0;
}
/*
sp1.use_count() = 2
sp2.use_count() = 2
Deconstruction A
*/

weak_ptr章節(jié)我們繼續(xù)講解使用shared_from_this()的原因。

  1. 避免循環(huán)引用。循環(huán)引用會導致內(nèi)存泄漏,比如:

#include <iostream>
#include <memory>
using namespace std;class A;
class B;class A {
public:std::shared_ptr<B> bptr;~A() {cout << "A is deleted" << endl;}
};class B {
public:std::shared_ptr<A> aptr;~B() {cout << "B is deleted" << endl;  // 析構(gòu)函數(shù)后,才去釋放成員變量}
};int main()
{std::shared_ptr<A> pa;{std::shared_ptr<A> ap(new A);std::shared_ptr<B> bp(new B);ap->bptr = bp;bp->aptr = ap;pa = ap;// 是否可以手動釋放呢?
//        ap.reset();ap->bptr.reset(); // 手動釋放成員變量才行}cout<< "main leave. pa.use_count()" << pa.use_count() << endl;  // 循環(huán)引用導致ap bp退出了作用域都沒有析構(gòu)return 0;
}/*
B is deleted
main leave. pa.use_count()1
A is deleted
*/

循環(huán)引用導致apbp的引用計數(shù)為2,在離開作用域之后,apbp的引用計數(shù)減為1,并不回減為0,導 致兩個指針都不會被析構(gòu),產(chǎn)生內(nèi)存泄漏。

解決的辦法是把A和B任何一個成員變量改為weak_ptr,具體方法見weak_ptr章節(jié)。

  • 什么是循環(huán)引用?

循環(huán)引用(circular reference)是指在編程中,兩個或多個對象之間形成一個循環(huán)的引用關系,導致這些對象之間的內(nèi)存無法被正確釋放,從而引發(fā)內(nèi)存泄漏。這種情況也被稱為循環(huán)依賴或循環(huán)關聯(lián)。

unique_ptr獨占的智能指針

unique_ptr是一個獨占型的智能指針,它不允許其他的智能指針共享其內(nèi)部的指針,不允許通過賦值將 一個unique_ptr賦值給另一個unique_ptr。下面的錯誤示例。

unique_ptr<T> my_ptr(new T);
unique_ptr<T> my_other_ptr = my_ptr; // 報錯,不能復制

unique_ptr不允許復制,但可以通過函數(shù)返回給其他的unique_ptr,還可以通過std::move來轉(zhuǎn)移到其 他的unique_ptr,這樣它本身就不再擁有原來指針的所有權(quán)了。例如

unique_ptr<T> my_ptr(new T); // 正確
unique_ptr<T> my_other_ptr = std::move(my_ptr); // 正確
unique_ptr<T> ptr = my_ptr; // 報錯,不能復制

std::make_shared是c++11的一部分,但std::make_unique不是。它是在c++14里加入標準庫的。

auto upw1(std::make_unique<Widget>()); // with make func
std::unique_ptr<Widget> upw2(new Widget); // without make func

使用new的版本重復了被創(chuàng)建對象的鍵入,但是make_unique函數(shù)則沒有。重復類型違背了軟件工程的 一個重要原則:應該避免代碼重復,代碼中的重復會引起編譯次數(shù)增加,導致目標代碼膨脹。

除了unique_ptr的獨占性, unique_ptr和shared_ptr還有一些區(qū)別,比如

  • unique_ptr可以指向一個數(shù)組,代碼如下所示

std::unique_ptr<int []> ptr(new int[10]);
ptr[9] = 9;
std::shared_ptr<int []> ptr2(new int[10]); // 這個是不合法的
  • unique_ptr指定刪除器和shared_ptr有區(qū)別

std::shared_ptr<int> ptr3(new int(1), [](int *p){delete p;}); // 正確
std::unique_ptr<int> ptr4(new int(1), [](int *p){delete p;}); // 錯誤

unique_ptr需要確定刪除器的類型,所以不能像shared_ptr那樣直接指定刪除器,可以這樣寫:

std::unique_ptr<int, void(*)(int*)> ptr5(new int(1), [](int *p){delete p;}); //正確

關于shared_ptr和unique_ptr的使用場景是要根據(jù)實際應用需求來選擇。如果希望只有一個智能指針管 理資源或者管理數(shù)組就用unique_ptr,如果希望多個智能指針管理同一個資源就用shared_ptr。

#include <iostream>
#include <memory>
using namespace std;struct MyDelete
{void operator()(int *p){cout << "delete" << endl;delete p;}
};int main()
{auto upw1(std::make_unique<int[]>(2));     // with make func  make_unique需要設置c++14std::unique_ptr<int> upw2(new int); // without make funcupw1[21] = 1;std::unique_ptr<int,MyDelete> ptr2(new int(1));
//    auto ptr(std::make_unique<int, MyDelete>(1));cout << "main finish! " << upw1[1] << endl;return 0;
}/*
main finish! 0
delete
*/

weak_ptr弱引用的智能指針

share_ptr雖然已經(jīng)很好用了,但是有一點share_ptr智能指針還是有內(nèi)存泄露的情況,當兩個對象相互 使用一個shared_ptr成員變量指向?qū)Ψ?#xff0c;會造成循環(huán)引用,使引用計數(shù)失效,從而導致內(nèi)存泄漏。

weak_ptr 是一種不控制對象生命周期的智能指針, 它指向一個 shared_ptr 管理的對象. 進行該對象的內(nèi) 存管理的是那個強引用的shared_ptr, weak_ptr只是提供了對管理對象的一個訪問手段。weak_ptr 設 計的目的是為配合 shared_ptr 而引入的一種智能指針來協(xié)助 shared_ptr 工作, 它只可以從一個 shared_ptr 或另一個 weak_ptr 對象構(gòu)造, 它的構(gòu)造和析構(gòu)不會引起引用記數(shù)的增加或減少。weak_ptr 是用來解決shared_ptr相互引用時的死鎖問題,如果說兩個shared_ptr相互引用,那么這兩個指針的引 用計數(shù)永遠不可能下降為0,資源永遠不會釋放。它是對對象的一種弱引用,不會增加對象的引用計數(shù), 和shared_ptr之間可以相互轉(zhuǎn)化,shared_ptr可以直接賦值給它,它可以通過調(diào)用lock函數(shù)來獲得 shared_ptr。?

weak_ptr沒有重載操作符*和->,因為它不共享指針,不能操作資源,主要是為了通過shared_ptr獲得 資源的監(jiān)測權(quán),它的構(gòu)造不會增加引用計數(shù),它的析構(gòu)也不會減少引用計數(shù),純粹只是作為一個旁觀者 來監(jiān)視shared_ptr中管理的資源是否存在。weak_ptr還可以返回this指針和解決循環(huán)引用的問題。

weak_ptr的基本用法

  1. 通過use_count()方法獲取當前觀察資源的引用計數(shù),如下所示:

shared_ptr<int> sp(new int(10));
weak_ptr<int> wp(sp);
cout << wp.use_count() << endl; //結(jié)果講輸出1
  1. 通過expired()方法判斷所觀察資源是否已經(jīng)釋放,如下所示:

shared_ptr<int> sp(new int(10));
weak_ptr<int> wp(sp);
if(wp.expired())cout << "weak_ptr無效,資源已釋放";
elsecout << "weak_ptr有效";
  1. 通過lock方法獲取監(jiān)視的shared_ptr,如下所示:

std::weak_ptr<int> gw;
void f()
{if(gw.expired()) {cout << "gw無效,資源已釋放";}else {auto spt = gw.lock();cout << "gw有效, *spt = " << *spt << endl;}
}int main()
{{auto sp = atd::make_shared<int>(42);gw = sp;f();}f();return 0;
}

weak_ptr返回this指針

shared_ptr章節(jié)中提到不能直接將this指針返回shared_ptr,需要通過派生 std::enable_shared_from_this類,并通過其方法shared_from_this來返回指針,原因是 std::enable_shared_from_this類中有一個weak_ptr,這個weak_ptr用來觀察this智能指針,調(diào)用 shared_from_this()方法是,會調(diào)用內(nèi)部這個weak_ptr的lock()方法,將所觀察的shared_ptr返回,再看 前面的范例

//1-1-shared_from_this2
#include <iostream>
#include <memory>using namespace std;class A: public std::enable_shared_from_this<A>
{
public:shared_ptr<A>GetSelf(){return shared_from_this(); }~A(){cout << "Deconstruction A" << endl;}
};int main()
{// auto spp = make_shared<A>();shared_ptr<A> sp1(new A);shared_ptr<A> sp2 = sp1->GetSelf();  // ok//    shared_ptr<A> sp2;//    {//        shared_ptr<A> sp1(new A);//        sp2 = sp1->GetSelf();  // ok//    }cout << "sp1.use_count() = " << sp1.use_count()<< endl;cout << "sp2.use_count() = " << sp2.use_count()<< endl;return 0;
}
/*
sp1.use_count() = 2
sp2.use_count() = 2
Deconstruction A
*/

在外面創(chuàng)建A對象的智能指針和通過對象返回this的智能指針都是安全的,因為shared_from_this()是內(nèi) 部的weak_ptr調(diào)用lock()方法之后返回的智能指針,在離開作用域之后,spy的引用計數(shù)減為0,A對象會被析構(gòu),不會出現(xiàn)A對象被析構(gòu)兩次的問題。

需要注意的是,獲取自身智能指針的函數(shù)盡量在shared_ptr的構(gòu)造函數(shù)被調(diào)用之后才能使用,因為 enable_shared_from_this內(nèi)部的weak_ptr只有通過shared_ptr才能構(gòu)造。

weak_ptr解決循環(huán)引用問題

在shared_ptr章節(jié)提到智能指針循環(huán)引用的問題,因為智能指針的循環(huán)引用會導致內(nèi)存泄漏,可以通過 weak_ptr解決該問題,只要將A或B的任意一個成員變量改為weak_ptr

#include <iostream>
#include <memory>
using namespace std;class A;
class B;class A {
public:std::weak_ptr<B> bptr; // 修改為weak_ptrint *val;A() {val = new int(1);}~A() {cout << "A is deleted" << endl;delete  val;}
};class B {
public:std::shared_ptr<A> aptr;~B() {cout << "B is deleted" << endl;}
};//weak_ptr 是一種不控制對象生命周期的智能指針,
void test()
{std::shared_ptr<A> ap(new A);std::weak_ptr<A> wp1 = ap;std::weak_ptr<A> wp2 = ap;cout<< "ap.use_count()" << ap.use_count()<< endl;
}void test2()
{std::weak_ptr<A> wp;{std::shared_ptr<A> ap(new A);wp = ap;}cout<< "wp.use_count()" << wp.use_count() << ", wp.expired():" << wp.expired() << endl;if(!wp.expired()) {// wp不能直接操作對象的成員、方法std::shared_ptr<A> ptr = wp.lock(); // 需要先lock獲取std::shared_ptr<A>*(ptr->val) = 20;  }
}int main()
{test2();
//    {
//        std::shared_ptr<A> ap(new A);
//        std::shared_ptr<B> bp(new B);
//        ap->bptr = bp;
//        bp->aptr = ap;
//    }cout<< "main leave" << endl;return 0;
}
/*
A is deleted
wp.use_count()0, wp.expired():1
main leave
*/

這樣在對B的成員賦值時,即執(zhí)行bp->aptr=ap;時,由于aptr是weak_ptr,它并不會增加引用計數(shù),所 以ap的引用計數(shù)仍然會是1,在離開作用域之后,ap的引用計數(shù)為減為0,A指針會被析構(gòu),析構(gòu)后其內(nèi) 部的bptr的引用計數(shù)會被減為1,然后在離開作用域后bp引用計數(shù)又從1減為0,B對象也被析構(gòu),不會發(fā) 生內(nèi)存泄漏。

weak_ptr使用注意事項

  1. weak_ptr在使用前需要檢查合法性。

weak_ptr<int> wp;
{shared_ptr<int> sp(new int(1)); //sp.use_count()==1wp = sp; //wp不會改變引用計數(shù),所以sp.use_count()==1shared_ptr<int> sp_ok = wp.lock(); //wp沒有重載->操作符。只能這樣取所指向的對象
}
shared_ptr<int> sp_null = wp.lock(); //sp_null .use_count()==0;

因為上述代碼中sp和sp_ok離開了作用域,其容納的K對象已經(jīng)被釋放了。 得到了一個容納NULL指針的sp_null對象。在使用wp前需要調(diào)用wp.expired()函數(shù)判斷一下。 因為wp還仍舊存在,雖然引用計數(shù)等于0,仍有某處“全局”性的存儲塊保存著這個計數(shù)信息。直到最后 一個weak_ptr對象被析構(gòu),這塊“堆”存儲塊才能被回收。

如果shared_ptr sp_ok和weak_ptr wp;屬于同一個作用域呢?如下所示:

weak_ptr<int> wp;
shared_ptr<int> sp_ok;
{shared_ptr<int> sp(new int(1)); //sp.use_count()==1wp = sp; //wp不會改變引用計數(shù),所以sp.use_count()==1sp_ok = wp.lock(); //wp沒有重載->操作符。只能這樣取所指向的對象
}
if(wp.expired()) {cout << "shared_ptr is destroy" << endl;
} else {cout << "shared_ptr no destroy" << endl;
}/*
shared_ptr no destroy
*/
http://www.risenshineclean.com/news/4895.html

相關文章:

  • ps和dw 做網(wǎng)站百度賬號怎么改名字
  • 好的做彩平圖的網(wǎng)站百度手機助手下載安裝
  • 自建免費網(wǎng)站朋友圈廣告代理商官網(wǎng)
  • 如何用域名建網(wǎng)站策劃公司排行榜
  • 網(wǎng)站建設高清圖片百度在線客服系統(tǒng)
  • 織夢移動端網(wǎng)站模板下載如何在百度搜索到自己的網(wǎng)站
  • 國外 網(wǎng)站 設計發(fā)布軟文網(wǎng)站
  • 青浦教育平臺網(wǎng)站建設網(wǎng)頁制作接單平臺
  • 設計師門戶網(wǎng)站程序必應搜索網(wǎng)站
  • 招遠網(wǎng)站定制北大青鳥培訓機構(gòu)靠譜嗎
  • 專業(yè)網(wǎng)站建設顧問長沙網(wǎng)站托管seo優(yōu)化公司
  • 遂寧做網(wǎng)站2022百度收錄越來越難了
  • 網(wǎng)站制作費會計分錄怎么做企業(yè)網(wǎng)站推廣方法
  • 做公益做的好的的網(wǎng)站上海外貿(mào)網(wǎng)站seo
  • 住房和城鄉(xiāng)建設部監(jiān)理工程師網(wǎng)站關鍵詞推廣方式
  • 蘇州公司技術(shù)支持 蘇州網(wǎng)站建設百度收錄什么意思
  • 網(wǎng)站統(tǒng)計開放平臺近期新聞熱點大事件
  • wordpress 箭頭翻頁seo牛人
  • 哪里學網(wǎng)站建設與管理網(wǎng)絡軟文發(fā)布平臺
  • 沈陽個人做網(wǎng)站推廣網(wǎng)站哪個好
  • 做商城網(wǎng)站的公司app營銷推廣方案
  • 南潯哪有做網(wǎng)站的網(wǎng)絡推廣工具
  • 蘭州最新大事電腦優(yōu)化用什么軟件好
  • wordpress 小說站主題百度賬號人工客服電話
  • 云服務器是什么站長工具seo綜合查詢推廣
  • 本地服務器網(wǎng)站建設google推廣怎么做
  • 網(wǎng)站別人給我做的備案 我能更改嗎外包推廣服務
  • 用jsp和mysql做網(wǎng)站短視頻怎么賺錢
  • 二字順口名字公司廣告優(yōu)化師的工作內(nèi)容
  • 網(wǎng)站導航廣告怎么做什么軟件比百度搜索好