共享智能指針是指多個(gè)智能指針可以同時(shí)管理同一塊有效的內(nèi)存,共享智能指針shared_ptr是一個(gè)模板類,如果要進(jìn)行初始化有三種方式:通過構(gòu)造函數(shù)、std::make_shared輔助函數(shù)以及reset方法。共享智能指針對(duì)象初始化完畢后就指向了要管理的那塊堆內(nèi)存,如果想要查看當(dāng)前有多少智能指針同時(shí)管理著這塊內(nèi)存可以使用共享智能指針提供的一個(gè)成員函數(shù)use_count,函數(shù)原型如下:
// 管理當(dāng)前對(duì)象的 shared_ptr 實(shí)例數(shù)量,或若無被管理對(duì)象則為 0。
long use_count() const noexcept;
1.1、通過構(gòu)造函數(shù)初始化// shared_ptr類模板中,提供了多種實(shí)用的構(gòu)造函數(shù), 語法格式如下:
std::shared_ptr智能指針名字(創(chuàng)建堆內(nèi)存);
測(cè)試代碼如下:
#include#includeusing namespace std;
int main()
{// 使用智能指針管理一塊 int 型的堆內(nèi)存
shared_ptrptr1(new int(520));
cout<< "ptr1.use_count: "<< ptr1.use_count()<< endl;
// 使用智能指針管理一塊字符數(shù)組對(duì)應(yīng)的堆內(nèi)存
shared_ptrptr2(new char[12]);
cout<< "ptr2.use_count: "<< ptr2.use_count()<< endl;
// 創(chuàng)建智能指針對(duì)象, 不管理任何內(nèi)存
shared_ptrptr3;
cout<< "ptr3.use_count: "<< ptr3.use_count()<< endl;
// 創(chuàng)建智能指針對(duì)象, 初始化為空
shared_ptrptr4(nullptr);
cout<< "ptr4.use_count: "<< ptr4.use_count()<< endl;
return 0;
}
測(cè)試代碼的輸出結(jié)果:
注意:如果智能指針被初始化一塊有效內(nèi)存,那么這塊內(nèi)存的引用計(jì)數(shù)+1,如果智能指針沒有被初始化或者被初始化為nullptr空指針,引用計(jì)數(shù)不會(huì)+1,另外,不要使用一個(gè)原始指針初始化多個(gè)shared_ptr。
int *p = new int;
shared_ptrp1(p);
shared_ptrp2(p); // error, 編譯不會(huì)報(bào)錯(cuò), 運(yùn)行會(huì)出錯(cuò),指針p已經(jīng)初始化了p1了
1.2、通過拷貝和移動(dòng)構(gòu)造函數(shù)初始化當(dāng)一個(gè)智能指針被初始化之后,就可以通過這個(gè)智能指針初始化其他新對(duì)象。在創(chuàng)建新對(duì)象的時(shí)候,對(duì)應(yīng)的拷貝構(gòu)造函數(shù)或者移動(dòng)構(gòu)造函數(shù)就可以被自動(dòng)調(diào)用。
#include#includeusing namespace std;
int main()
{// 使用智能指針管理一塊 int 型的堆內(nèi)存, 內(nèi)部引用計(jì)數(shù)為 1
shared_ptrptr1(new int(520));
cout<< "ptr1管理的內(nèi)存引用計(jì)數(shù): "<< ptr1.use_count()<< endl;
//調(diào)用拷貝構(gòu)造函數(shù)
shared_ptrptr2(ptr1);
cout<< "ptr2管理的內(nèi)存引用計(jì)數(shù): "<< ptr2.use_count()<< endl;
shared_ptrptr3 = ptr1;
cout<< "ptr3管理的內(nèi)存引用計(jì)數(shù): "<< ptr3.use_count()<< endl;
//調(diào)用移動(dòng)構(gòu)造函數(shù)
shared_ptrptr4(std::move(ptr1));
cout<< "ptr4管理的內(nèi)存引用計(jì)數(shù): "<< ptr4.use_count()<< endl;
std::shared_ptrptr5 = std::move(ptr2);
cout<< "ptr5管理的內(nèi)存引用計(jì)數(shù): "<< ptr5.use_count()<< endl;
return 0;
}
測(cè)試代碼輸出的結(jié)果:
1.3、通過std::make_shared初始化注意:如果使用拷貝的方式初始化共享智能指針對(duì)象,這兩個(gè)對(duì)象會(huì)同時(shí)管理同一塊堆內(nèi)存,堆內(nèi)存對(duì)應(yīng)的引用計(jì)數(shù)也會(huì)增加;如果使用移動(dòng)的方式初始化智能指針對(duì)象,只是轉(zhuǎn)讓了內(nèi)存的所有權(quán),管理內(nèi)存的對(duì)象并不會(huì)增加,因此內(nèi)存引用計(jì)數(shù)不會(huì)變化。
通過C++提供的std::make_shared()就可以完成內(nèi)存對(duì)象的創(chuàng)建并將其初始化給智能指針,函數(shù)原型如下:
template< class T, class... Args >shared_ptrmake_shared( Args&&... args );
測(cè)試代碼如下:
#include#include#includeusing namespace std;
class Test
{public:
Test()
{cout<< "construct Test..."<< endl;
}
Test(int x)
{cout<< "construct Test, x = "<< x<< endl;
}
Test(string str)
{cout<< "construct Test, str = "<< str<< endl;
}
~Test()
{cout<< "destruct Test ..."<< endl;
}
};
int main()
{// 使用智能指針管理一塊 int 型的堆內(nèi)存, 內(nèi)部引用計(jì)數(shù)為 1
shared_ptrptr1 = make_shared(520);
cout<< "ptr1管理的內(nèi)存引用計(jì)數(shù): "<< ptr1.use_count()<< endl;
//使用智能指針管理一塊無參Test類類型的內(nèi)存,內(nèi)部引用計(jì)數(shù)為1
shared_ptrptr2 = make_shared();
cout<< "ptr2管理的內(nèi)存引用計(jì)數(shù): "<< ptr2.use_count()<< endl;
//使用智能指針管理一塊帶有int類型參數(shù)的Test類類型的內(nèi)存,內(nèi)部引用計(jì)數(shù)為1
shared_ptrptr3 = make_shared(520);
cout<< "ptr3管理的內(nèi)存引用計(jì)數(shù): "<< ptr3.use_count()<< endl;
//使用智能指針管理一塊string類型參數(shù)的Test類類型的內(nèi)存,內(nèi)部引用計(jì)數(shù)為1
shared_ptrptr4 = make_shared("Naruto");
cout<< "ptr4管理的內(nèi)存引用計(jì)數(shù): "<< ptr4.use_count()<< endl;
return 0;
}
測(cè)試代碼的輸出結(jié)果:
1.4、通過reset方法初始化注意:使用st::make_shared()模板函數(shù)可以完成內(nèi)存地址的創(chuàng)建,并將最終的內(nèi)存地址傳遞給共享智能指針對(duì)象管理。如果申請(qǐng)的內(nèi)存是普通類型,通過函數(shù)的()可完成地址的初始化,如果要?jiǎng)?chuàng)建一個(gè)類對(duì)象,函數(shù)的()內(nèi)部需要指定構(gòu)造函數(shù)對(duì)象需要的參數(shù),也就是類構(gòu)造函數(shù)的參數(shù),則使用std::make_shared()初始化。
共享智能指針類提供的std::shared_ptr::reset方法函數(shù)原型如下:
void reset() noexcept;
template< class Y >void reset( Y* ptr );
template< class Y, class Deleter >void reset( Y* ptr, Deleter d );
template< class Y, class Deleter, class Alloc >void reset( Y* ptr, Deleter d, Alloc alloc );
測(cè)試代碼如下:
#include#include#includeusing namespace std;
int main()
{// 使用智能指針管理一塊 int 型的堆內(nèi)存, 內(nèi)部引用計(jì)數(shù)為 1
shared_ptrptr1 = make_shared(520);
//拷貝賦值,引用計(jì)數(shù)加1
shared_ptrptr2 = ptr1;
shared_ptrptr3 = ptr1;
shared_ptrptr4 = ptr1;
cout<< "ptr1.use_count: "<< ptr1.use_count()<< endl;
cout<< "ptr2.use_count: "<< ptr2.use_count()<< endl;
cout<< "ptr3.use_count: "<< ptr3.use_count()<< endl;
cout<< "ptr4.use_count: "<< ptr4.use_count()<< endl;
cout<< endl;
//釋放智能指針指向的內(nèi)存,清空引用計(jì)數(shù)
ptr4.reset();
cout<< "ptr1.use_count: "<< ptr1.use_count()<< endl;
cout<< "ptr2.use_count: "<< ptr2.use_count()<< endl;
cout<< "ptr3.use_count: "<< ptr3.use_count()<< endl;
cout<< "ptr4.use_count: "<< ptr4.use_count()<< endl;
cout<< endl;
shared_ptrptr5;
//初始化智能指針,引用計(jì)數(shù)加1
ptr5.reset(new int(250));
cout<< "ptr5.use_count: "<< ptr5.use_count()<< endl;
return 0;
}
測(cè)試代碼輸出結(jié)果:
對(duì)應(yīng)用基礎(chǔ)數(shù)據(jù)類型來說,通過操作智能指針和操作智能指針管理內(nèi)存效果是一樣的,可以直接完成數(shù)據(jù)的讀寫。
但是如果共享智能指針管理的是一個(gè)對(duì)象,那么就需要去除原始內(nèi)存地址再操作,可以調(diào)用共享智能指針類提供的get方法得到原始地址,其函數(shù)原型如下:
T* get() const noexcept;
測(cè)試代碼如下:
#include#include#includeusing namespace std;
int main()
{int len = 128;
shared_ptrptr(new char[len]);
// 得到指針的原始地址
char* add = ptr.get();
//初始化字符串
memset(add, 0, len);
//字符串拷貝
strcpy(add, "I will be Naruto !!!");
cout<< "string: "<< add<< endl;
shared_ptrp(new int);
*p = 100;
cout<< *p.get()<< " "<< *p<< endl;
return 0;
}
測(cè)試代碼的結(jié)果:
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購(gòu),新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧