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
28
C++11 Smart Pointers
Matt
March 11, 2015
Tweet
Share
More Decks by Matt
See All by Matt
C++11 Lambda
chchwy
1
59
Other Decks in Technology
See All in Technology
25分で解説する「最小権限の原則」を実現するための AWS「ポリシー」大全 / 20250625-aws-summit-aws-policy
opelab
9
1.2k
How Community Opened Global Doors
hiroramos4
PRO
1
120
Windows 11 で AWS Documentation MCP Server 接続実践/practical-aws-documentation-mcp-server-connection-on-windows-11
emiki
0
1k
2025-06-26_Lightning_Talk_for_Lightning_Talks
_hashimo2
2
100
より良いプロダクトの開発を目指して - 情報を中心としたプロダクト開発 #phpcon #phpcon2025
bengo4com
1
3.1k
rubygem開発で鍛える設計力
joker1007
2
220
製造業からパッケージ製品まで、あらゆる領域をカバー!生成AIを利用したテストシナリオ生成 / 20250627 Suguru Ishii
shift_evolve
PRO
1
140
Amazon ECS & AWS Fargate 運用アーキテクチャ2025 / Amazon ECS and AWS Fargate Ops Architecture 2025
iselegant
17
5.7k
Welcome to the LLM Club
koic
0
190
Yamla: Rustでつくるリアルタイム性を追求した機械学習基盤 / Yamla: A Rust-Based Machine Learning Platform Pursuing Real-Time Capabilities
lycorptech_jp
PRO
3
130
Oracle Cloud Infrastructure:2025年6月度サービス・アップデート
oracle4engineer
PRO
2
260
Clineを含めたAIエージェントを 大規模組織に導入し、投資対効果を考える / Introducing AI agents into your organization
i35_267
4
1.7k
Featured
See All Featured
Making the Leap to Tech Lead
cromwellryan
134
9.4k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
17
940
Facilitating Awesome Meetings
lara
54
6.4k
The Invisible Side of Design
smashingmag
300
51k
Raft: Consensus for Rubyists
vanstee
140
7k
Navigating Team Friction
lara
187
15k
How to Ace a Technical Interview
jacobian
277
23k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
32
2.3k
Mobile First: as difficult as doing things right
swwweet
223
9.7k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
34
5.9k
4 Signs Your Business is Dying
shpigford
184
22k
Optimizing for Happiness
mojombo
379
70k
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)