#include <iostream>
#include <memory>
#include <vector>
using namespace std;
/*
1.shared_ptr允許多個(gè)指針指向同一個(gè)對(duì)象。
2.shared_ptr定義在memory頭文件中。
3.默認(rèn)初始化的智能指針中保存著一個(gè)空指針。
4.智能指針的使用方式與普通指針類似,解引用一個(gè)智能指針返回它指向的對(duì)象咽扇,是對(duì)象,而不是一個(gè)指針。
5.最安全的分配和使用動(dòng)態(tài)內(nèi)存的方法是調(diào)用一個(gè)名為make_shared的標(biāo)準(zhǔn)函數(shù)佳遣,
此函數(shù)在動(dòng)態(tài)內(nèi)存中分配一個(gè)對(duì)象并初始化它识埋,返回指向此對(duì)象的shared_ptr。
6.調(diào)用make_shared在定義在memory文件當(dāng)中零渐。
7.調(diào)用make_shared<string>時(shí)窒舟,傳遞的參數(shù)必須與string的某個(gè)構(gòu)造函數(shù)相匹配,
調(diào)用make_shared<int>時(shí)傳遞的參數(shù)必須能用來初始化一個(gè)int诵盼,以此類推惠豺。
如果我們不傳遞任何參數(shù),對(duì)象就會(huì)進(jìn)行值初始化风宁。
8.通常用auto定義一個(gè)對(duì)象來保存make_shared的結(jié)果
9.若p.unique()為1洁墙,返回true,否則返回false戒财。
10.當(dāng)進(jìn)行拷貝或賦值操作時(shí)热监,每隔shared_ptr都會(huì)記錄有多少個(gè)其他shared_ptr指向相同的對(duì)象,
可以認(rèn)為每個(gè)shared_ptr都有一個(gè)關(guān)聯(lián)的計(jì)數(shù)器饮寞,通常稱其為引用計(jì)數(shù)孝扛,無論何時(shí)我們拷貝一個(gè)shared_ptr,
計(jì)數(shù)器都會(huì)遞增幽崩。
11.r = q苦始,q的引用計(jì)數(shù)增加,r的引用計(jì)數(shù)先遞減慌申,然后指向q指向的對(duì)象陌选,r的引用計(jì)數(shù)加1。
12.shared_ptr析構(gòu)函數(shù)會(huì)遞減它所指向的引用計(jì)數(shù)蹄溉。如果引用計(jì)數(shù)變?yōu)?咨油,shared_ptr的析構(gòu)函數(shù)就會(huì)銷毀對(duì)象,
并釋放它的內(nèi)存类缤。
13.接受指針參數(shù)的智能指針構(gòu)造函數(shù)是explicit的臼勉,因此我們不能將一個(gè)內(nèi)置指針隱式轉(zhuǎn)換為一個(gè)智能指針,
必須使用直接初始化形式來初始化一個(gè)智能指針餐弱。
14.不能進(jìn)行內(nèi)置指針到智能指針的隱式轉(zhuǎn)換宴霸。
15.默認(rèn)情況下,一個(gè)用來初始化智能指針的普通指針必須指向動(dòng)態(tài)內(nèi)存膏蚓,因?yàn)橹悄苤羔樐J(rèn)使用delete釋放它所關(guān)聯(lián)的對(duì)象瓢谢。
16.不要使用get初始化另一個(gè)智能指針或?yàn)橹悄苤羔樫x值
17.使用get返回的指針的代碼不能delete此指針
18.shared_ptr沒有release函數(shù)
*/
class Student
{
public:
Student() {
cout << "調(diào)用Student的默認(rèn)構(gòu)造函數(shù) name:" << m_name << endl;
}
Student(string name) : m_name(name) {
cout << "調(diào)用Student的自定義構(gòu)造函數(shù) name:" << m_name << endl;
}
Student(const Student &s) : m_name(s.m_name) {
cout << "調(diào)用Student的拷貝構(gòu)造函數(shù) name:" << m_name << endl;
}
~Student() {
cout << "調(diào)用Student的析構(gòu)函數(shù) name:" << m_name << endl;
}
string m_name;
int a;
};
auto deleter = [](Student *s) {
std::cout << "deleter name:" << s->m_name << endl;
};
void test(shared_ptr<Student> s)
{
cout << "func:" << __func__
<< " line:" << __LINE__
<< " s:" << s
<< " s.use_count:"
<< s.use_count()
<< endl;
if (s.unique()) {
std::cout << "s is unique" << endl;
} else {
std::cout << "s is not unique" << endl;
}
}
void test_local(Student s) {
cout << "func:" << __func__ << " line:" << __LINE__ << endl;
s.m_name = "許攸";
}
// 傳給函數(shù)一個(gè)臨時(shí)的shared_ptr,很可能導(dǎo)致錯(cuò)誤
void test_01()
{
// test_local的實(shí)參是一個(gè)Student類的對(duì)象驮瞧,接收郭嘉的是test_local函數(shù)的形參
// 當(dāng)執(zhí)行到test_local函數(shù)內(nèi)部時(shí)氓扛,對(duì)象郭嘉沒有被銷毀,直到test_local執(zhí)行完后,
// Student對(duì)象才會(huì)被銷毀
// 郭嘉的生命周期在test_local函數(shù)中
test_local(Student("郭嘉"));
Student *s = new Student("燕青");
/*
* 合法采郎,但是s所指向的內(nèi)存會(huì)被釋放
* 因?yàn)橛闷胀ㄖ羔榮初始化一個(gè)智能指針千所,智能指針?biāo)竷?nèi)存和普通指針s所指向內(nèi)存相同
* 此智能指針創(chuàng)建后,test函數(shù)的形參接收Student的智能指針
* 當(dāng)test函數(shù)調(diào)用過后蒜埋,智能指針將會(huì)引用計(jì)數(shù)減一淫痰,當(dāng)引用計(jì)數(shù)為0時(shí),釋放所指內(nèi)存
* test執(zhí)行完成后整份,s指針指向的內(nèi)存釋放待错,但是s還是指向原來的內(nèi)存空間
*/
// 形參接收實(shí)參創(chuàng)建的智能指針
test(shared_ptr<Student> (s));
if (s) {
cout << "s is not nullptr 但s所指向的內(nèi)存已經(jīng)被釋放了" << endl;
} else {
cout << "s is nullptr" << endl;
}
cout << __func__ << "函數(shù)結(jié)束" << endl;
}
// unique
void test_02()
{
shared_ptr<Student> s1 = make_shared<Student>("衛(wèi)青");
if (s1.unique()) {
std::cout << "a1 is unique" << endl;
} else {
std::cout << "a1 is not unique" << endl;
}
std::cout << endl;
shared_ptr<Student> s2 = s1;
if (s2.unique()) {
std::cout << "s2 is unique" << endl;
} else {
std::cout << "s2 is not unique use_count:" << s2.use_count() << endl;
}
cout << "s1.name:" << s1->m_name << endl;
cout << "s2.name:" << s2->m_name << endl;
cout << "s1:" << s2 << " s2:" << s2 << endl;
cout << __func__ << "函數(shù)結(jié)束" << endl;
}
// 添加刪除器
void test_03()
{
shared_ptr<Student> s1(new Student("步驚云"), deleter);
cout << "s1:" << s1 << endl;
/*
* error:
* no matching function for call to
* 'std::__cxx11::basic_string<char>::basic_string(std::__cxx11::basic_string<char>*, main()::<lambda(std::__cxx11::string*)>&)'
* { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
*/
// make_shared不允許自定義刪除器
// shared_ptr<Student> s2 = make_shared<Student>(new Student("步驚云"), deleter);
// 添加刪除器
s1.reset(new Student("步天"), deleter);
cout << "s1.name:" << s1->m_name << " s1:" << s1 << endl;
cout << __func__ << "函數(shù)結(jié)束" << endl;
}
// shared_ptr的use_count
void test_04()
{
// Student("朱重八")當(dāng)做make_shared的參數(shù),是局部變量烈评,make_shared執(zhí)行完后火俄,Student("朱重八")要被釋放掉
shared_ptr<Student> s1 = make_shared<Student>(Student("朱重八"));
cout << "s1.name:" << s1->m_name << endl;
shared_ptr<Student> s2 = make_shared<Student>(Student("朱標(biāo)"));
cout << "s2.name:" << s2->m_name << endl;
// use_count的效率很低,僅用于調(diào)試
cout << "s1.use_count:" << s1.use_count() << endl;
cout << "s2.use_count:" << s2.use_count() << endl;
s1 = s2;
cout << "s1.use_count:" << s1.use_count() << endl;
cout << "s2.use_count:" << s2.use_count() << endl;
cout << __func__ << "函數(shù)結(jié)束" << endl;
}
shared_ptr<Student> FuncCreateStudent(Student *s)
{
cout << "func:" << __func__
<< " line:" << __LINE__ << endl;
auto s1 = make_shared<Student>(*s);
// 智能指針和智能指針內(nèi)保存的普通指針指向的地址不同
cout << "s1.get:" << s1.get()
<< " s1:" << s1
<< " s:" << s
<< endl;
// 智能指針和智能指針包含的普通指針讲冠,兩個(gè)指針的地址不同
auto p = s1.get();
cout << "&s1.get:" << &p
<< " &s1:" << &s1
<< endl;
/*
* 執(zhí)行完make_shared<Student>(*s);后瓜客,因?yàn)闆]有定義變量接受make_shared返回的臨時(shí)智能指針,
* 所以智能指針銷毀
*/
// 這里是深拷貝沟启,不是淺拷貝忆家,所有普通指針s所指向的內(nèi)存沒有被釋放
make_shared<Student>(*s);
std::cout << "func:" << __func__
<< " line:" << __LINE__
<< " s.name:" << s->m_name
<< endl;
// 尚可喜return后不釋放犹菇,返回到調(diào)用函數(shù)當(dāng)中繼續(xù)使用
return make_shared<Student>("尚可喜");
}
void test_05()
{
auto s1 = new Student("吳應(yīng)熊");
auto s2 = FuncCreateStudent(s1);
std::cout << "s1->m_name:" << s1->m_name
<< " s2->m_name:" << s2->m_name
<< endl;
std::cout << "s2.use_count:" << s2.use_count() << endl;
cout << __func__ << "函數(shù)結(jié)束" << endl;
}
void test_06()
{
Student *s1 = new Student("鰲拜");
auto s2 = make_shared<Student>(*s1);
auto s3 = new Student("索尼");
make_shared<Student>(*(s3));
/*make_shared返回的結(jié)果沒有賦值給智能指針德迹,
那么make_shared創(chuàng)建的智能指針就結(jié)束了生命周期,會(huì)調(diào)用析構(gòu)函數(shù)釋放內(nèi)存 */
make_shared<Student>("蘇克薩哈");
cout << __func__ << "函數(shù)結(jié)束" << endl;
}
// 判斷智能指針是否為空
void test_07()
{
// 默認(rèn)初始化的智能指針中保存著一個(gè)空指針揭芍。
shared_ptr<Student> s1;
if (s1) {
cout << "s1 is not nullptr" << endl;
} else {
cout << "s1 is nullptr" << endl;
}
shared_ptr<string> str;
cout << "func:" << __func__ << " line:" << __LINE__ << endl;
// str包含的指針為空胳搞,空指針調(diào)用empty函數(shù)崩潰
// if (str->empty()) {
// cout << "str->empty is empty " << endl;
// }
cout << "func:" << __func__ << " line:" << __LINE__ << endl;
shared_ptr<Student> s2 = make_shared<Student>("遏必隆");
// s1->m_name等價(jià)于(*s1).m_name
// s1.get()返回s1中保存的指針
cout << __func__ << "函數(shù)結(jié)束" << endl;
}
void test_08()
{
Student *s1 = new Student("多隆");
cout << "s1->m_name:" << s1->m_name << " s1:" << s1 << endl;
{
// 這種方式創(chuàng)建的shared_ptr<Student>指針?biāo)竷?nèi)存地址和s1所指內(nèi)存地址是一樣的
shared_ptr<Student> s2(s1);
Student *s3 = s2.get();
cout << "s2->m_name:" << s2->m_name << " s2->use_count:" << s2.use_count() << endl;
cout << "s1:" << s1 << " s2:" << s2 << " s3:" << s3 << endl;
cout << endl;
}
// a1所指的內(nèi)存已經(jīng)被釋放,所有不能訪問a1的成員變量
// cout << "s1->m_name:" << s1->m_name << endl;
Student *s4 = new Student("豪格");
cout << "s4->m_name:" << s4->m_name << " s4:" << s4 << endl;
{
auto s5 = make_shared<Student>(*s4);
cout << "s5->m_name:" << s5->m_name
<< " s5->use_count:" << s5.use_count()
<< endl;
cout << endl;
}
cout << "s1->m_name:" << s1->m_name << " s1:" << s1 << endl;
cout << __func__ << "函數(shù)結(jié)束" << endl;
}
// 智能指針解引用
void test_09()
{
shared_ptr<int> p1(new int(10));
shared_ptr<int> p2 = make_shared<int>(10);
cout << "*p1:" << *p1 << endl;
cout << "*p2:" << *p2 << endl;
cout << __func__ << "函數(shù)結(jié)束" << endl;
}
void test_10()
{
// 調(diào)用自定義構(gòu)造函數(shù)
Student *s1 = new Student("岱宗");
shared_ptr<Student> s2(s1);
// 調(diào)用自定義構(gòu)造函數(shù)
shared_ptr<Student> s3 = make_shared<Student>("宋江");
shared_ptr<Student> s4(s3);
cout << __func__ << "函數(shù)結(jié)束" << endl;
}
void test_11()
{
unique_ptr<int> q(new int(10));
// error:書上說這樣可以称杨,但是代碼里面不行
// shared_ptr<int> p1(q);
cout << __func__ << "函數(shù)結(jié)束" << endl;
}
void test_12()
{
shared_ptr<Student> s1 = make_shared<Student>("甘寧");
cout << "s1:" << s1 << endl;
// 在test函數(shù)形參的引用計(jì)數(shù)為2肌毅,s1和形參指向同一塊內(nèi)存
test(s1);
cout << __func__ << "函數(shù)結(jié)束" << endl;
}
void test_13()
{
shared_ptr<Student> s1 = make_shared<Student>("s1");
Student *s2 = s1.get();
// 錯(cuò)誤:使用get返回的指針不能使用delete釋放
delete s2;
s2 = nullptr;
cout << __func__ << "函數(shù)結(jié)束" << endl;
}
void test_14()
{
shared_ptr<Student> s1 = make_shared<Student>("甘興霸");
// 先創(chuàng)建
s1.reset(new Student("孫策"));
cout << "s1.name:" << s1->m_name << endl;
cout << __func__ << "函數(shù)結(jié)束" << endl;
}
void test_15()
{
// 默認(rèn)初始化的智能指針不調(diào)用構(gòu)造函數(shù),智能指針s1為空姑原,智能指針中保存空指針
shared_ptr<Student> s1;
if (s1) {
cout << "s1不為空" << endl;
} else {
cout << "s1為空" << endl;
}
shared_ptr<Student> s2 = make_shared<Student>("張飛");
if (s2) {
cout << "s2不為空 name:" << s2->m_name << endl;
} else {
cout << "s2為空" << endl;
}
// 智能指針s3不為空
shared_ptr<Student> s3 = make_shared<Student>();
if (s3) {
cout << "s3不為空 name:" << s3->m_name << endl;
} else {
cout << "s3為空" << endl;
}
}
void test_16(vector<shared_ptr<Student>> &vec)
{
auto s1 = make_shared<Student>("張飛");
auto s2 = make_shared<Student>("劉備");
auto s3 = make_shared<Student>("關(guān)羽");
cout << "s1.a:" << s1->a << endl;
vec.push_back(s1);
vec.push_back(s2);
vec.push_back(s3);
cout << "s1.use_count:" << s1.use_count() << endl;
cout << "s2.use_count:" << s2.use_count() << endl;
cout << "s3.use_count:" << s3.use_count() << endl;
}
void test_17(vector<shared_ptr<Student>> &vec)
{
for (size_t i = 0; i < vec.size(); i++) {
cout << "func:" << __func__
<< " line:" << __LINE__
<< "name:" << vec[i]->m_name
<< " use_count:" << vec[i].use_count()
<< endl;
}
for (auto v : vec) {
cout << "v.name:" << v->m_name
<< " use_count:" << v.use_count()
<< endl;
}
for (size_t i = 0; i < vec.size(); i++) {
cout << "func:" << __func__
<< " line:" << __LINE__
<< "name:" << vec[i]->m_name
<< " use_count:" << vec[i].use_count()
<< endl;
}
// 容器內(nèi)的shared_ptr只有調(diào)用erase悬而,才會(huì)引用計(jì)數(shù)減一
for (auto it = vec.begin(); it != vec.end();) {
it = vec.erase(it);
}
cout << "func:" << __func__ << " 結(jié)束" << endl;
}
void test_18()
{
shared_ptr<Student> s1 = make_shared<Student>("孫悟空");
// shared_ptr沒有release函數(shù)
// s1.release();
}
void test_19()
{
shared_ptr<Student> sp1 = make_shared<Student>("孫悟空");
shared_ptr<Student> sp2 = sp1;
cout << "sp1.use_count:" << sp1.use_count()
<< " sp2.use_count:" << sp2.use_count()
<< endl;
// 調(diào)用reset將sp1的引用計(jì)數(shù)減一
sp1.reset();
cout << "sp1.use_count:" << sp1.use_count()
<< " sp2.use_count:" << sp2.use_count()
<< endl;
sp2.reset();
cout << "func:" << __func__ << " 結(jié)束" << endl;
}
// 動(dòng)態(tài)分配的const對(duì)象
void test_20()
{
const int *pi1 = new int();
cout << "*pi1:" << *pi1 << endl;
pi1 = new int(11);
cout << "*pi1:" << *pi1 << endl;
cout << "func:" << __func__ << " 結(jié)束" << endl;
}
int main()
{
system("chcp 65001");
// test_00();
// test_01();
// test_02();
// test_03();
// test_04();
// test_05();
// test_06();
// test_07();
// test_08();
// test_09();
// test_10();
// test_11();
// test_12();
// test_13();
// test_14();
vector<shared_ptr<Student>> vec;
// test_16(vec);
// test_17(vec);
// test_18();
// test_19();
test_20();
return 0;
}
shared_ptr總結(jié)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
- 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來配名,“玉大人啤咽,你說我怎么就攤上這事晋辆。” “怎么了宇整?”我有些...
- 文/不壞的土叔 我叫張陵栈拖,是天一觀的道長。 經(jīng)常有香客問我没陡,道長涩哟,這世上最難降的妖魔是什么? 我笑而不...
- 正文 為了忘掉前任盼玄,我火速辦了婚禮贴彼,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘埃儿。我一直安慰自己器仗,他們只是感情好,可當(dāng)我...
- 文/花漫 我一把揭開白布童番。 她就那樣靜靜地躺著精钮,像睡著了一般。 火紅的嫁衣襯著肌膚如雪剃斧。 梳的紋絲不亂的頭發(fā)上轨香,一...
- 文/蒼蘭香墨 我猛地睜開眼简逮,長吁一口氣:“原來是場噩夢啊……” “哼球散!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起散庶,我...
- 序言:老撾萬榮一對(duì)情侶失蹤蕉堰,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后督赤,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體嘁灯,經(jīng)...
- 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
- 正文 我和宋清朗相戀三年躲舌,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了丑婿。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
- 正文 年R本政府宣布迁筛,位于F島的核電站,受9級(jí)特大地震影響耕挨,放射性物質(zhì)發(fā)生泄漏细卧。R本人自食惡果不足惜,卻給世界環(huán)境...
- 文/蒙蒙 一筒占、第九天 我趴在偏房一處隱蔽的房頂上張望贪庙。 院中可真熱鬧,春花似錦翰苫、人聲如沸止邮。這莊子的主人今日做“春日...
- 文/蒼蘭香墨 我抬頭看了看天上的太陽导披。三九已至,卻和暖如春埃唯,著一層夾襖步出監(jiān)牢的瞬間撩匕,已是汗流浹背。 一陣腳步聲響...
- 正文 我出身青樓巍实,卻偏偏與公主長得像,于是被迫代替她去往敵國和親哩牍。 傳聞我的和親對(duì)象是個(gè)殘疾皇子棚潦,可洞房花燭夜當(dāng)晚...
推薦閱讀更多精彩內(nèi)容
- 注 make_shared & shared_ptr make_shared 和 shared_ptr 的用處 通...
- 有使用 C++ 做開發(fā)的童鞋應(yīng)該都經(jīng)歷過被 指針 折磨荚孵,使用指針的使用需要保證 new 和 delete 對(duì)齊妹窖,如...
- 智能指針在C++11版本之后提供,包含在頭文件<memory>中收叶,shared_ptr骄呼、unique_ptr、we...
- 0 現(xiàn)摘錄一篇不錯(cuò)的講Shared_ptr的文章,要點(diǎn)記錄如下: 智能指針是為了管理針對(duì)于異常蜓萄、線程間等的內(nèi)存隅茎,防...
- gcc 代碼:git://gcc.gnu.org/git/gcc.git[git://gcc.gnu.org/gi...