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
750
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
8
6.7k
ripgrep をライブラリとして使う
rhysd
0
790
port-monolith-to-wasm-for-chrome-extension
rhysd
0
580
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
なぜCTOを降りてFDEを選んだのか?〜なぜプロダクト企業がFDEで顧客の現場に踏み込むのか〜
gonta
1
190
動作中のプログラムの中身をリアルタイムに覗く / Realtime Debugger for CSharp with Roslyn
prota
1
1.8k
【加筆修正版】Laravel のアプリケーションをどこにデプロイするか #phpcon_ehime
akase244
0
150
すこし踏み込む CancellationToken
htkym
2
1.7k
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
560
AI時代のコードレビューは人に向けるな、仕組みに向けろ
texmeijin
5
3.6k
最近”作らせてる” ローカルAIアプリの話
akit37
0
450
Turning Architecture into Unit Tests in the AI Era (NSSpain XIV)
steliosf
PRO
1
140
setup-vp GitLab対応の裏側
naokihaba
0
160
mrbgem 三角測量 開発
ogom
0
240
プロダクトコードからライブラリの境界を見つける
elmetal
PRO
0
110
Agentic Software Factoryに、すごく賢いIF文を。 / super smart IF statement into the Agentic Software Factory.
rkaga
8
2.1k
Featured
See All Featured
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4.6k
Into the Great Unknown - MozCon
thekraken
41
2.8k
Bash Introduction
62gerente
615
220k
Utilizing Notion as your number one productivity tool
mfonobong
4
620
Embracing the Ebb and Flow
colly
88
5.2k
The Organizational Zoo: Understanding Human Behavior Agility Through Metaphoric Constructive Conversations (based on the works of Arthur Shelley, Ph.D)
kimpetersen
PRO
0
490
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
11
1.1k
The innovator’s Mindset - Leading Through an Era of Exponential Change - McGill University 2025
jdejongh
PRO
1
370
Fantastic passwords and where to find them - at NoRuKo
philnash
53
4k
Navigating Weather and Climate Data
rabernat
0
550
SEO Brein meetup: CTRL+C is not how to scale international SEO
lindahogenes
2
2.9k
We Analyzed 250 Million AI Search Results: Here's What I Found
joshbly
2
2k
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