Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Effective Modern C++ Item19, Item20
Search
Linda_pp
April 22, 2015
Programming
740
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Effective Modern C++ Item19, Item20
shared_ptr と weak_ptr の概要および内部的な話など.
Effective Modern C++ 読書会 4/22(水)
Linda_pp
April 22, 2015
More Decks by Linda_pp
See All by Linda_pp
actionlint の Linter 設計
rhysd
7
6.6k
ripgrep をライブラリとして使う
rhysd
0
770
port-monolith-to-wasm-for-chrome-extension
rhysd
0
570
Fuzzing Rust Text Editor
rhysd
1
3.1k
Vim compiled to WebAssembly
rhysd
5
2.4k
about-neovim-0.4.0-floating-window
rhysd
3
2.4k
reply.vim
rhysd
0
1.4k
Vim ported to WebAssembly (VimConf 2018)
rhysd
4
3.6k
go-selfupdate-github で ツールを自己アップデートする
rhysd
5
4.7k
Other Decks in Programming
See All in Programming
業務時間外もAIに働いてもらう話
colorful12
3
10k
AGENTS.md Is Not Enough:Build Skills, Don't Download Them
lx_t
0
110
ハーネス設計入門 〜プロンプト、コンテキストの次〜
kinopeee
56
38k
モバイル交通系ICへのチャージ実例から考える、クロスプラットフォーム開発におけるiOS実機テスト設計とCI運用
yusuga
1
320
Swift愛好会と私(ウホーイ) / Swift Fan Club and Uhooi
uhooi
0
150
LL言語やWebフレームワークのPostgreSQL対応 〜DBの機能がユーザーに届くまで〜
kentaroutakeda
0
150
Kiroで創り、AgentCoreで繋ぐ!AWSで実践する「AI-DLC」から「AIエージェント統合」までの最新地図
licux
4
650
フロントエンドUIフレームワークのこれまでとこれから
ssssota
5
2.4k
Intent as Code
shoppingjaws
6
910
Snowflakeで業務アプリを作ろう。 Snowflakeのアプリ機能解説&実践ガイド
ayumu_yamaguchi
1
230
XP祭りでしか伝わらないフリップネタ #xpjug
murabayashi
0
140
Family mrubyの進捗
kishima
1
110
Featured
See All Featured
How Software Deployment tools have changed in the past 20 years
geshan
1
34k
A Modern Web Designer's Workflow
chriscoyier
699
190k
Six Lessons from altMBA
skipperchong
29
4.5k
Dominate Local Search Results - an insider guide to GBP, reviews, and Local SEO
greggifford
PRO
0
330
エンジニアに許された特別な時間の終わり
watany
108
250k
Bioeconomy Workshop: Dr. Julius Ecuru, Opportunities for a Bioeconomy in West Africa
akademiya2063
PRO
1
350
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
46
3k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
38
3k
Building a Modern Day E-commerce SEO Strategy
aleyda
45
9.2k
Building Flexible Design Systems
yeseniaperezcruz
330
41k
Become a Pro
speakerdeck
PRO
31
6.2k
Impact Scores and Hybrid Strategies: The future of link building
tamaranovitovic
0
440
Transcript
Effective Modern C++ ಡॻձ Item 19, Item 20
@Linda_pp @rhysd झຯͰίϯύΠϥͱ͔ͭͬͯ͘·͢ɽ https://github.com/rhysd/Dachs
Item 19: ॴ༗ݖΛڞ༗͍ͨ͠Ϧ ιʔεͷཧʹ std::shared_ptr Λ͓͏
C++ ʹ͓͚ΔϝϞϦཧ Q.ʮͳΜͯݪ࢝తͳΜͩʂ1960ͷLisp ʹԿֶͳ ͔ͬͨͷ͔ʁϦιʔεਓؒͰͳ͘Ϛγϯ͕ཧ͖ͩ͢ʯ ! A.ʮϝϞϦ͚͕ͩϦιʔεͰͳ͍͠ɼϝϞϦ͕։์͞Ε ΔλΠϛϯά͕͔Βͳ͍ͷࠔΔɽԶୡී௨ͷ༧ଌͰ ͖ΔσετϥΫλ͕ྑ͍Μͩɽʯ Q
C++ ʹ͓͚ΔϝϞϦཧ ͦ͏͍ͬͯΓ GC ศརɽGCͱϝϞ Ϧखಈཧͷؒͷଘࡏ͕΄͍͠ɽ → std::shared_ptr Q
std::shared_ptr • Ϧιʔεͷॴ༗ݖΛࢀরΧϯτʹΑͬͯཧ͢ ΔϙΠϯλΫϥε • ϦιʔεΛॴ༗͍ͯ͠Δ shared_ptr ͷΛΧ ϯτ͓͖ͯ͠ɼΧϯτ͕ 0
ʹͳͬͨ࣌ʹϦ ιʔεͷσετϥΫλΛ࣮ߦ͢Δ • GC ͷΑ͏ʹࣗಈཧ͞ΕɼϦιʔεͷղ์λ Πϛϯά͕༧ଌՄೳͰ͋Δɽ Q
{ std::shared_ptr<int> p1{new Widget}; { auto p2 = p1; }
} std::shared_ptr 8JEHFU Q DPOTUSVDU DPOTUSVDU Q
{ std::shared_ptr<int> p1{new Widget}; { auto p2 = p1; }
} std::shared_ptr 8JEHFU Q Q DPOTUSVDU Q
{ std::shared_ptr<int> p1{new Widget}; { auto p2 = p1; }
} std::shared_ptr 8JEHFU Q Q EFTUSPZ Q
{ std::shared_ptr<int> p1{new Widget}; { auto p2 = p1; }
} std::shared_ptr 8JEHFU Q EFTUSPZ EFTUSPZ Q
ࢀরΧϯτͷίετ • shared_ptr ͷαΠζ → ੜϙΠϯλͷ2ഒʢ࣮ ࡍʹίϯτϩʔϧϒϩοΫʢޙड़ʣʣ • ϝϞϦϦιʔεಈతʹ֬อ͢Δඞཁ͕͋Δ •
ࢀরΧϯτͷૢ࡞ atomic Ͱ͋Δ (thread safety) Q
ࢀরΧϯτͷίετͷճආ • move ίϯετϥΫλΛ͏ͱࢀরΧϯτ มԽ͠ͳ͍ʢॴ༗ݖͷҠৡʣ ! ! • ʢ͜ͷଞʹ͠Ͱͳ͘ࢀর͠ʹ͢Δͳ ͲͰࢀরΧϯτͷ্ԼΛ͛Δʣ
Q std::shared_ptr<int> p1{new int}; ! // ࢀরΧϯτมԽͤͣɼp1 ʹ null ͕ೖ͞ΕΔ std::shared_ptr<int> p2{ std::move(p1) };
shared_ptr ͷσϦʔλ • unique_ptr ͱҧ͍ɼσϦʔλ͕ܕͷҰ෦Ͱ ͳ͍ʢtype erasure ʹΑΔ࣮ʣ auto loggingDel
= [](Widget *pw) { makeLogEntry(pw); delete pw; }; ! std::unique_ptr<Widget, decltype(loggingDel)> upw(new Widget, loggingDel); ! std::shared_ptr<Widget> spw(new Widget, loggingDel); Q
shared_ptr ͷσϦʔλ • ҟͳΔσϦʔλΛ࣋ͭෳͷ shared_ptr Λ1 ͭͷίϯςφͰཧͨ͠Γɼޓ͍ʹೖͰ͖ ͨΓ͢Δ ! !
! • ݸਓతʹ͜ΕͰԿ͕خ͍͠ͷ͔Α͔͘Βͳ͍Ͱ͕͢ɼͲ͏ͤ control block ࢀরΧϯτͳͲΛผ్ׂ ΓͯΔͳΒ type erasure Ͱফ͠ͱ͚ͱ͍͏ײ͡ͳͷ͔ͳ… auto customDeleter1 = [](Widget *pw) { ... }; auto customDeleter2 = [](Widget *pw) { ... }; ! std::shared_ptr<Widget> pw1(new Widget, customDeleter1); std::shared_ptr<Widget> pw2(new Widget, customDeleter2); ! std::vector<std::shared_ptr<Widget>> vpw{ pw1, pw2 }; Q
shared_ptr ͷαΠζ • unique_ptr ͱҟͳΓɼৗʹϙΠϯλ2ͭ • ͋ΕɼͰΧελϜσϦʔλͷαΠζ…ʁ • → ΧελϜσϦʔλͳͲผͷॴʹ֬อ
͞ΕΔʢޙड़ʣ Q
shared_ptr ͷ෦ߏ 1PJOUFSUP5 1PJOUFSUP$POUSPM#MPDL 50CKFDU 3FGFSFODF$PVOU 8FBL$PVOU 0UIFS%BUB DVTUPNEFMFUFS
BMMPDBUPS FUD TIBSFE@QUS5 $POUSPM#MPDL 3FTPVSDF Q
Control Block • ࢀরΧϯτऑࢀরΧϯτͳͲͷཧ ใΛ࣋ͭ • ཧରͷΦϒδΣΫτ͕ੜ͞Εͨ࣌ʹ1 ͚ͩੜ͞ΕΔ • Χϯτ͕྆ํ0ʹͳͬͨ࣌ʹഁغ͞ΕΔ
Q
Control Block ͷੜλΠϛϯά • std::make_shared() ͕ݺΕͨ࣌ • unique_ptr auto_ptr
Λݩʹ shared_ptr ͕ ͭ͘ΒΕͨ࣌ • ੜϙΠϯλΛݩʹ shared_ptr ͕ͭ͘ΒΕͨ࣌ Q $POUSPM#MPDLϦιʔεʹର͚ͯͭͩ͠ੜ ͠ͳ͚ΕͳΒͳ͍ʢϓϩάϥϚͷʣ
Control Block ͕ॏෳ͢Δྫ ಉ͡ੜϙΠϯλΛݩʹ2ճ shared_ptr Λੜ ͢Δͱ Control Block ͕ॏෳͯ͠͠·͏
auto pw = new Widget; ! std::shared_ptr<Widget> spw1(pw, loggingDel); // Control Block ੜ ! std::shared_ptr<Widget> spw2(pw, loggingDel); // 2ͭΛੜ ! // spw1 ͱ spw2 ͦΕͧΕผݸʹ pw Λཧͯ͠͠·͍ͬͯΔͷͰɼ // σϦʔλ2ճݺΕͯ͠·͏ʢະఆٛಈ࡞ʣ Q
Control Block ͕ॏෳ͢Δྫ • جຊతʹ std::make_shared() Λ͏͖ • ੜϙΠϯλ͔ΒͰͳ͘ shared_ptr
͔Β shared_ptr Λੜ͢Δ ! ! ! • ࠓճΧελϜΞϩέʔλΛࢦఆ͍ͯ͠ΔͷͰ make_shared ͑ͳ͍ɽͳ͓ɼΞϩ έʔλΛࢦఆ͍ͨ͠߹ std::allocate_shared() ͕͋Δɽʢmake_shared_with_deleter() ͕΄͠ ͍ʣ auto pw = new Widget; ! std::shared_ptr<Widget> spw1(pw, loggingDel); // Control Block ੜ ! std::shared_ptr<Widget> spw2(spw1); // OK Q
Control Block ͕ॏෳ͢Δྫ this ͔Β shared_ptr Λੜ͢Δ߹ std::vector<std::shared_ptr<Widget>> processedWidgets; !
class Widget{ public: … void process(); … }; ! void Widget::process() { … processedWidgets.emplace_back(this); } Q
Control Block ͕ॏෳ͢Δྫ this ੜϙΠϯλͳͷͰɼprocess() ͕ݺΕ Δͨͼʹ৽͍͠ Control Block ͕ͭ͘ΒΕΔ
// ຊʹॻ͍ͯ·ͤΜ͕ɼ͜͏͍͏͜ͱ͕Γ͍ͨͣ ! std::shared_ptr<Widget> spw = std::make_shared(…); ! spw->process(); // NG ผͷ Control Block ͕ͭ͘ΒΕͯ͠·͏ Q
Control Block ͕ॏෳ͢Δྫ std::enable_shared_from_this Ϋϥεςϯϓ ϨʔτΛ͏͜ͱͰղܾ Q // Curiously Recurring
Template Pattern (CRTP) Λ࣮ͬͯ͞Ε͍ͯΔ class Widget : public std::enable_shared_from_this<Widget> { … }; ! void Widget::process() { … processedWidgets.emplace_back(shared_from_this()); }
std::enable_shared_from_this • ܧঝ͢Δͱϝϯόؔ shared_from_this() ͕͑ΔΑ͏ʹͳ ΔΫϥεςϯϓϨʔτ • shared_from_this() Control-Block
Λͭ͘Βͣʹ shared_ptr Λ࡞͢Δ • Control-Block ͕ແ͍߹ະఆٛಈ࡞ʢ͍͍ͨͯྫ֎ʣ • Control-Block ͕طʹ࡞͞Ε͍ͯΔඞཁ͕͋Δʢଞͷ shared_ptr ͕ͦͷΦϒδΣΫτΛࢦ͍ͯ͠Δඞཁ͕͋Δʣ Q
std::enable_shared_from_this enable_shared_from_this Λܧঝͨ͠Ϋϥε ඞͣ shared_ptr Ͱཧ͞ΕΔΑ͏ʹϑΝΫτ ϦؔΛͭ͘Δ class Widget :
public std::enable_shared_from_this<Widget> { public: template<typename… Ts> static std::shared_ptr<Widget> create(Ts &&… params) { return std::shared_ptr<Widget>{new Widget(std::forward<Ts>(params)…)}; } … ! private: … // ίϯετϥΫλఆٛ } Q
shared_ptr ͷίετ reasonable • Control Block ͷαΠζσϑΥϧτͰ3word • Control Block
࣮ʹԾؔΛ͍ͬͯΔ ͕ݺΕΔͷϦιʔε͕ഁغ͞ΕΔ1ճͷΈ • େͷϚγϯͰ atomic ͳૢ࡞1໋ྩͰ࣮ ߦͰ͖Δ Q
shared_ptr ͷίετ reasonable • एׯͷίετͱҾ͖͑ʹण໋ཧΛࣗಈͰ ߦ͑Δ • ͨͩ͠ॴ༗ݖΛڞ༗͢Δඞཁ͕ແ͍ͳΒ unique_ptr ͷ΄͏͕ྑ͍
• unique_ptr ඞཁʹԠͯ͡ shared_ptr ʹ ͤΔ Q
ྻͷཧ • C++14 ࣌Ͱ shared_ptr<T []> ߟྀ͞Ε͍ͯ ͳ͍ • std::vector
ͳͲͷίϯςφΛ͏͖ • C++17 Ͱྻͷαϙʔτ͕ఏҊ͞Ε͍ͯΔ ʢN3869, N3920, N3939ʣ • boost::shared_ptr ྻରԠࡁΈ Q
ྻͷཧ • ΧελϜσϦʔλΛͬͯ delete T[] ΛݺͿΑ ͏ʹͯ͠μϝ • operator[] ͕ແ͍
• جఈΫϥεͷ shared_ptr ͕ੜΫϥεͷΦ ϒδΣΫτΛࢦ͢ͱ͖ɼྻΛߟྀ͍ͯ͠ ͳ͍ Q
Things to Remember • shared_ptr ෳͷϙΠϯλʹڞ༗͞ΕΔϝϞϦҙͷϦ ιʔεͷण໋ཧΛߦ͑Δ • unique_ptr ͱൺͯαΠζ
atomic ͳૢ࡞ͳͲͷΦʔόʔϔο υ͕͋Δ • ϦιʔεͷഁغʹσϑΥϧτͰ delete ͕ΘΕΔ͕ɼΧελ ϜσϦʔλ͑ΔɽΧελϜσϦʔλ shared_ptr ͷܕʹӨ ڹΛ༩͑ͳ͍ • ੜϙΠϯλม͔Β shared_ptr Λͭ͘Δ͜ͱۃྗආ͚Δ͖ Q
Item20: ࢦ͢Ϧιʔε͕ແޮʹͳΓ ͏Δ shared_ptr ʹ std::weak_ptr Λ͓͏
ॴ༗ݖΛ࣋ͨͳ͍ϙΠϯλ • shared_ptr ͷΑ͏ʹಛఆͷϦιʔεΛࢦͤΔ ͕ɼॴ༗ݖ࣋ͨͳ͍ʢ=ࢀরΧϯτΛಈ͔ ͞ͳ͍ʣεϚʔτϙΠϯλ͕΄͍͠ • ͦͷϙΠϯλࢦ͍ͯ͠ΔϦιʔε͕ଞͷ shared_ptr ʹআ͞ΕΔՄೳੑ͕͋Δ
• ͦΕ std::weak_ptr ͰͰ͖ΔΑʂ Q
std::weak_ptr • dereference null νΣοΫͰ͖ͳ͍ • shared_ptr ͷঢ֨ͱࢦ͍ͯ͠ΔϦιʔε͕ ੜ͖͍ͯΔ͔Ͳ͏͔ͷνΣοΫ͕Ͱ͖Δ
• shared_ptr ͱҰॹʹ͏ʢ͍͍ͨͯ shared_ptr ͔Βੜ͞ΕΔʣ Q
auto spw = std::make_shared<Widget>(); ←ࠓίίʂ ! std::weak_ptr<Widget> wpw(spw); ! std::cout
<< wpw.expired() << std::endl; // false ! spw = nullptr; // Delete Widget object ! std::cout << wpw.expired() << std::endl; // true std::weak_ptr Q 8JEHFU TQX
auto spw = std::make_shared<Widget>(); ! std::weak_ptr<Widget> wpw(spw); ←ࠓίίʂ ! std::cout
<< wpw.expired() << std::endl; // false ! spw = nullptr; // Delete Widget object ! std::cout << wpw.expired() << std::endl; // true std::weak_ptr Q 8JEHFU TQX XQX
auto spw = std::make_shared<Widget>(); ! std::weak_ptr<Widget> wpw(spw); ! std::cout <<
wpw.expired() << std::endl; // false ! spw = nullptr; // Delete Widget object ←ࠓίίʂ ! std::cout << wpw.expired() << std::endl; // true std::weak_ptr Q 8JEHFU XQX
Race condition auto spw = std::make_shared<Widget>(); ! std::weak_ptr<Widget> wpw(spw); !
if (!wpw.expired()) { … // ͜͜ͰଞͷεϨουʹΑͬͯ spw ʹ nullptr ͕ೖ͞Εͯ͠·͏ … wpw.lock()->do_something(); // ະఆٛಈ࡞ } expired() ͷνΣοΫͷޙʹଞͷεϨουʹ ΑͬͯϦιʔε͕আ͞Εͯ͠·͏ͷͰʁ Q
Race condition auto spw = std::make_shared<Widget>(); std::weak_ptr<Widget> wpw(spw); ! //
wpw ͕ expire ͍ͯ͠Δͱ͖ spw2 null ʹͳΔ auto spw2 = wpw.lock(); ! // wpw ͕ expire ͍ͯ͠Δͱ͖ std::bad_weak_ptr ͕͛ΒΕΔ std::shared_ptr<Widget> spw3(wpw); → weak_ptr::lock() ͔ shared_ptr ͷίϯετϥΫλΛ ͏ Q ※ ݸਓతʹ if (auto spw = wpw.lock()) { … ͷΑ͏ʹॻ͚Δ lock() ͷ΄͏͕Φεεϝ
Ϣʔεέʔε1: Ωϟογϡ Item18ʹैͬͯ Widget Λੜ͠ unique_ptr Ͱฦ͢ϑΝΫτϦؔΛ࡞ ! ! loadWidget()
ॲཧ͕ॏ͍ͷͰ Widget ʹৼ ΒΕͨ ID ΛͬͯΩϟογϡ͍ͨ͠ std::unique_ptr<const Widget> loadWidget(WidgetID id); Q
std::unique_ptr<const Widget> loadWidget(WidgetID id); ! std::shared_ptr<const Widget> fastLoadWidget(WidgetID id) {
static std::unordered_map<WidgetID, std::weak_ptr<const Widget>> cache; ! // Ωϟογϡ͕ແ͍͔ expire ͍ͯ͠Δ࣌ objPtr ۭʹͳΔ auto objPtr = cache[id].lock(); ! // Ωϟογϡ͞Ε͍ͯͳ͚Ε৽͘͠ Widget Λͭ͘ΓɼΩϟογϡ͢Δ if (!objPtr) { objPtr = loadWidget(id); cache[id] = objPtr; } ! return objPtr; } Q Ϣʔεέʔε1: Ωϟογϡ
Ϣʔεέʔε1: Ωϟογϡ • ੜͨ͠Ϧιʔε͕ഁغ͞Ε͍ͯΔ͔Ͳ͏͔ΛΔඞ ཁ͕͋ΔͨΊɼweak_ptr ͰΩϟογϡ͢Δͷ͕ద • Ϧιʔεͷঢ়ଶΛΔͨΊʹΩϟογϡ͖ϑΝΫτ ϦؔͷΓ shared_ptr
ʹ͢Δඞཁ͕͋Δ (Control Block ͷ weak count) • expire ͨ͠ΩϟογϡͷআͳͲΛՃͯ͠ྑ͍ ͔͠Εͳ͍ Q
Ϣʔεέʔε2: Observer • observerʢsubject ͔Β௨Λड͚औΓԿ͔ॲཧΛ ߦ͏ʣ • subjectʢঢ়ଶΛ࣋ͪ observer ʹঢ়ଶͷมߋΛ௨
͢Δʣ • subject observer Λࢀর͢Δ͕ɼobserver ࢮ͵ ͜ͱ͕͋Δ → subject observer Λ weak_ptr Ͱ࣋ ͖ͭ Q
Ϣʔεέʔε2: Observer ͜Μͳײ͡ʁʢຊจதʹྫͳ͠ʣ class Subject { public: void register_observer(std::shared_ptr<Observer> const&
o) { observers.emplace_back(o); } ! void update_state() { for (auto const& w : observers) { if (auto const o = w.lock()) { o->notify(…); } } } ! private: std::vector<std::weak_ptr<Observer>> observers; }; Q
Ϣʔεέʔε3: σʔλߏ ! ! ! B ͕ A Λࢦ࣌͢ɼԿΛ͑ྑ͍͔ #
" $ TIBSFE@QUS TIBSFE@QUS Q
??? ͷ෦ʹԿΛ͑ྑ͍͔ • ੜϙΠϯλ → A ͕ഁغ͞Εͨ࣌ʹͦΕΛΔํ๏͕ͳ͍ NG • shared_ptr
→ ॥ࢀরͯ͠͠·͍ɼӬԕʹࢀরΧϯτ ͕ 0 ʹͳΒͳ͘ͳΔʢϝϞϦϦʔΫʣ NG • weak_ptr → A ͕ഁغ͞Ε͍ͯΔ͔Ͳ͏͔ΛΔ͜ͱ͕ Ͱ͖ɼA Λॴ༗͍ͯ͠ͳ͍ͷͰ॥ࢀরͳ͍ OK • ※ߏͰͷΈ͕ࢠΛ shared_ptr Ͱࢦ͢ͱ͍ͬͨಛघͳ݅Ͱ͋ΕࢠˠੜϙΠϯλͰྑ͍ Q
weak_ptr ͷίετ • αΠζ shared_ptr ͱಉ͡ʢshared_ptr ͱಉ ༷ʹ Control Block
Λར༻͢Δʣ • Χϯτͷૢ࡞ atomic Ͱ͋Δ → ࢀরΧ ϯτͰͳ͘ऑࢀরΧϯτΛૢ࡞͢Δ 3FGFSFODF$PVOU 8FBL$PVOU 0UIFS%BUB DVTUPNEFMFUFS BMMPDBUPS FUD $POUSPM#MPDL • Control Block ͯ͢ͷ weak_ptr ͕ ͍ͳ͘ͳͬͯॳΊͯআͰ͖ΔͷͰऑ ࢀরΛΧϯτ͢Δඞཁ͕͋ΔʢItem 21ʣ Q
Things to Remember • Ϧιʔε͕ແޮʹͳΔ͜ͱ͕͋Δ shared_ptr ͷΑ͏ͳϙΠϯλ͕΄͍࣌͠ std::weak_ptr Λ͏ •
weak_ptr ͷओͳϢʔεέʔεΩϟογϡɼ Φϒβʔόɼ॥ࢀরͷճආͳͲ Q