Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
C++11 Smart Pointers
Search
Matt
March 11, 2015
Technology
0
30
C++11 Smart Pointers
Matt
March 11, 2015
Tweet
Share
More Decks by Matt
See All by Matt
C++11 Lambda
chchwy
1
60
Other Decks in Technology
See All in Technology
Context Engineeringの取り組み
nutslove
0
270
インフラエンジニア必見!Kubernetesを用いたクラウドネイティブ設計ポイント大全
daitak
0
320
システムのアラート調査をサポートするAI Agentの紹介/Introduction to an AI Agent for System Alert Investigation
taddy_919
2
1.7k
Amazon S3 Vectorsを使って資格勉強用AIエージェントを構築してみた
usanchuu
3
430
Context Engineeringが企業で不可欠になる理由
hirosatogamo
PRO
2
380
Agile Leadership Summit Keynote 2026
m_seki
1
310
プロダクト成長を支える開発基盤とスケールに伴う課題
yuu26
3
1.2k
Amazon Bedrock AgentCore 認証・認可入門
hironobuiga
2
510
toCプロダクトにおけるAI機能開発のしくじりと学び / ai-product-failures-and-learnings
rince
6
5.5k
【インシデント入門】サイバー攻撃を受けた現場って何してるの?
shumei_ito
0
1.5k
茨城の思い出を振り返る ~CDKのセキュリティを添えて~ / 20260201 Mitsutoshi Matsuo
shift_evolve
PRO
1
180
今日から始めるAmazon Bedrock AgentCore
har1101
4
390
Featured
See All Featured
Building Better People: How to give real-time feedback that sticks.
wjessup
370
20k
Why Our Code Smells
bkeepers
PRO
340
58k
GraphQLとの向き合い方2022年版
quramy
50
14k
Art, The Web, and Tiny UX
lynnandtonic
304
21k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
31
3.1k
ラッコキーワード サービス紹介資料
rakko
1
2.2M
How to Think Like a Performance Engineer
csswizardry
28
2.4k
Why You Should Never Use an ORM
jnunemaker
PRO
61
9.7k
Noah Learner - AI + Me: how we built a GSC Bulk Export data pipeline
techseoconnect
PRO
0
100
Getting science done with accelerated Python computing platforms
jacobtomlinson
2
110
Build your cross-platform service in a week with App Engine
jlugia
234
18k
My Coaching Mixtape
mlcsv
0
46
Transcript
C++11 Smart Pointers 2015-03-10 Matthew
Outline • Why smart pointer? • std::unique_ptr • std::shared_ptr •
std::weak_ptr • Conclusion
Why smart pointer? 當我們拿到一個 Foo* ptr 時... 1. 你其實不知道它是單一物件還是 array.
2. 你不知道該怎麼銷毀它. a. delete ? delete[] ? ->Release()? Finalize()? 3. 保證(考慮所有路線可能後)剛好 delete 一次. 4. 你不知道這個指標是否還有效... …from Effective Modern C++
Smart pointer! • C++11 引入三種 smart pointer 來管理資源. • #include
<memory> • unique_ptr: for exclusive-ownership. • share_ptr: for shared-ownership. • weak_ptr: if pointers that can dangle.
for exclusive-ownership std::unique_ptr
std::uniqre_ptr • 最簡單的 smart pointer • 適用於物件只有一個 owner 時 •
當 unique_ptr 消滅時, 會順帶釋放持有資源.
適用場景 void f() { ClassA* ptr = new ClassA; …
// do something delete ptr; } if ( error ) { return; }
適用場景 void f() { std::unique_ptr<ClassA> ptr(new ClassA); … // do
something if ( error ) { return; } //delete ptr; no longer necessary. }
建立 unique_ptr // 傳入 raw pointer unique_ptr< string > up(
new string("nico") ); // 使用 make_unique function auto up = make_unique< string >( "nico" );
std::unique_ptr 用法 // unique_ptr 覆寫了 *, -> 運算子 // 所以用法和一般
pointer 差不多 (*up)[0] = 'N'; up->append("lai"); cout << *up << endl;
std::unique_ptr 管理動態分配陣列 // 也可以管理陣列, 用[]運算子存取 unique_ptr< int[] > up2( new
int[10] ); for ( int i = 0; i < 10; ++i) cout << up2[ i ];
std::unique_ptr 檢查 // 檢查指標有效性 if ( up ) { …
} if ( up != nullptr ) { … } // 釋放所有權 (立刻釋放資源) up.release();
std::unique_ptr 用法 // 不接受隱式轉換成 raw pointer (Compiler Error!) unique_ptr<string> up
= new string(""); string* p = up; // 如果你真的要取得 raw pointer… string* p = up.get(); //後果自行負責
// 不能分享所有權, 也不能copy unique_ptr unique_ptr<string> up2 = up; (Compiler Error!)
// 要用 std::move 顯式轉移 unique_ptr<string> up2 = std::move(up); // 轉移之後up失去所有權, onwer 變成了up2 cout << (up == nullptr); // true cout << (up2 == nullptr); // false
std::unique_ptr tips vector< unique_ptr<string> > kVec; // up 不能複製, 要用
reference 的方式取 for ( auto& up : kVec ) { cout << *up; }
std::unique_ptr 很適合持有 member class MyClass { unique_ptr<Foo> m_spFoo; public: MyClass()
: m_spFoo( make_unique<Foo>( 1, "Bar" ) ) {} ~MyClass() { /* 不需要在 destructor 釋放資源 */ } void DoSomething() { m_spFoo->bar(); } };
for shared-ownership. std::shared_ptr
std::shared_ptr 概念 • 由多個物件共享該資源的持有權 • 允許多個 smart pointer 指向同一個物件 •
只有所有的 shared_ptr 都消滅後,才會釋放 持有資源 (reference count)
建立 std::shared_ptr // 傳入 raw_pointer shared_ptr<string> sp( new string("nico") );
// 呼叫 make_shared function (Recommend!) // make_shared is more efficient. auto sp = make_shared<string>( "nico" );
std::shared_ptr 用法 auto sp = make_shared<string>( "nico" ); cout <<
(*sp)[ 0 ]; // print 'n' sp->replace(0, 1, 'N'); // "Nico" string* p = sp.get(); // get raw pointer if ( sp ) { … } if ( sp != nullptr ) { … } if ( sp == nullptr ) { … }
std::shared_ptr 可以分享持有權 auto sp = make_shared< QImage >( "icon.png" );
auto sp2( sp ); // via copy constructor auto sp3 = sp; // via assignment DoSomething( sp ); // pass as parameter sp.reset(); // 釋放所有權 sp2.reset( new QImage ); // 改持有另一個 raw ptr
std::shared_ptr 可以分享持有權 auto sp = make_shared< string >( "nico" );
auto sp2 = sp; vector< shared_ptr<string> > kVec; kVec.push_back( sp ); kVec.push_back( sp2 ); cout << sp.use_count() << endl; // 4
specify deleter // shared_ptr 可以指定釋放資源的方式 FILE* fp = fopen("log.txt", "w");
shared_ptr<FILE> sp( fp, CloseFile ); void CloseFile( FILE* f ) { cout << "File Closed!"; fclose( f ); }
specify deleter // shared_ptr 可以指定釋放資源的方式 FILE* fp = fopen("log.txt", "w");
shared_ptr<FILE> sp( fp, [] ( FILE* f ) { cout << "File Closed!"; fclose(f); } );
type cast // static_pointer_cast() // dynamic_pointer_cast() // const_pointer_cast() void f(
share_ptr<CBase> spBase ) { share_ptr<CNode> spNode = dynamic_pointer_cast< CNode >( spBase ); }
if pointers that can dangle. std::weak_ptr
std::weak_ptr 概念 • 有時候我們不希望共享物件的"持有權"… • 但是又不想用 raw pointer… • 用
weak_ptr! • weak_ptr 可以存取 shared_ptr 管理的物件, 但是不會增加 ref count.
避免 reference cycle Bank Customer share_ptr<Customer> share_ptr<Bank> 無法自動釋放!! share_ptr<Bank>
避免 reference cycle Bank Customer share_ptr<Customer> weak_ptr<Bank> 自動釋放OK!! share_ptr<Bank>
建立 weak_ptr // weak_ptr 不能單獨存在! weak_ptr<QImage> wp( new QImage );
// 必須依附於 shared_ptr. shared_ptr<QImage> sp( new QImage("icon.png") ); weak_ptr<QImage> wp( sp );
weak_ptr 用法 // weak_ptr 「沒有」覆寫 *, -> 運算子 // 所以不能像一般
pointer 使用 weak_ptr< string > wp( sp ); (*wp)[0] = 'N'; // Compiler Error! wp->append("lai"); // Compiler Error!
// 必須呼叫 lock() 轉成 share_ptr 才能用 weak_ptr< string > wp(
sp2 ); if ( auto& sp = wp.lock() ) { sp->append( "lai" ); cout << *sp; } else { cout << "Object is deleted."; }
weak_ptr 用法 weak_ptr< string > wp( sp ); // weak_ptr
可以 copy weak_ptr< string > wp2 = wp; wp.reset(); // 釋放物件指標 wp.expired(); // 詢問物件還在否?
auto sp = make_shared<string>( "Hello" ); weak_ptr<string> wp( sp );
cout << *sp ; // print 'Hello' cout << *wp.lock() ; // print 'Hello' cout << wp.expired(); // print 'false' sp.reset(); // release resource. cout << wp.expired(); // print 'true' cout << *wp.lock(); // throw exception!
Dangerous! Don't do that. CImage* pImage = new CImage; //
不要用兩個 smart pointer 管理同一個 raw pointer !! share_ptr<CImage> sp( pImage ); share_ptr<CImage> sp2( pImage );
Conclusion • C++11 想要消滅 delete keyword. • C++11 想要消滅 90%
的 new keyword. • 思考資源的持有權, 來挑選 smart pointer. • 如果不確定要用哪個, 先選 unique_ptr ◦ 因為 unique_ptr 幾乎沒有 cost • share_ptr 有一些 cost ◦ double pointer size (space cost) ◦ reference count. (performance cost)
Reference • http://www.cplusplus.com/reference/memory/ • MSDN: How to: Create and Use
shared_ptr Instances • The C++ Standard Library 2ed. (Book) • Effective Modern C++ (Book)