1(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[63130],{40028:(e,n,s)=>{"use strict";s.d(n,{A:()=>c,b:()=>r});var a=s(37876);function c({className:e="h-64"}){return(0,a.jsx)("div",{className:`${e} animate-pulse rounded-xl bg-zinc-100 dark:bg-zinc-800`})}function r(){return(0,a.jsx)("div",{className:"h-48 animate-pulse rounded-xl bg-zinc-100 dark:bg-zinc-800"})}},72696:(e,n,s)=>{"use strict";s.r(n),s.d(n,{SmartPointersDemo:()=>d,__N_SSG:()=>o,default:()=>x,meta:()=>h});var a=s(37876),c=s(91668),r=s(35674),i=s(18847),t=s.n(i),l=s(40028),o=!0;let d=t()(()=>Promise.all([s.e(10985),s.e(88007)]).then(s.bind(s,88007)),{loadableGenerated:{webpack:()=>[88007]},ssr:!1,loading:l.A}),h={title:"Smart Pointers in Modern C++",description:"Master C++11 smart pointers through interactive examples. Learn unique_ptr, shared_ptr, and weak_ptr with reference counting visualizations.",category:"language-internals",date:"2025-01-15",slug:"language-internals/smart-pointers",tags:["programming","cpp","memory-mgmt","patterns"],keywords:["smart pointers c++11","unique_ptr tutorial","shared_ptr reference counting","weak_ptr explained","automatic memory management","modern c++ pointers","memory safety c++"]},p=e=>(0,a.jsx)(r.b,Object.assign({meta:h},e));function m(e){let n=Object.assign({h2:"h2",a:"a",p:"p",h3:"h3",ol:"ol",li:"li",strong:"strong",code:"code",ul:"ul",pre:"pre",span:"span"},(0,c.RP)(),e.components),{RelatedConceptsGrid:s}=n;return s||function(e,n){throw Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}("RelatedConceptsGrid",!0),(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.h2,{id:"smart-pointers-modern-c-memory-management",children:(0,a.jsx)(n.a,{className:"heading-link",href:"#smart-pointers-modern-c-memory-management",children:"Smart Pointers: Modern C++ Memory Management"})}),"\n",(0,a.jsx)(n.p,{children:"Smart pointers were introduced in C++11 to provide automatic memory management while maintaining the performance characteristics of C++. They use RAII to ensure proper resource cleanup and eliminate most memory-related bugs."}),"\n",(0,a.jsx)(n.h3,{id:"the-three-smart-pointers",children:(0,a.jsx)(n.a,{className:"heading-link",href:"#the-three-smart-pointers",children:"The Three Smart Pointers"})}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:(0,a.jsx)(n.code,{children:"std::unique_ptr"})}),": Exclusive ownership"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:(0,a.jsx)(n.code,{children:"std::shared_ptr"})}),": Shared ownership with reference counting"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:(0,a.jsx)(n.code,{children:"std::weak_ptr"})}),": Non-owning observation"]}),"\n"]}),"\n",(0,a.jsx)(d,{}),"\n",(0,a.jsx)(n.h2,{id:"unique-pointer-stdunique_ptr",children:(0,a.jsxs)(n.a,{className:"heading-link",href:"#unique-pointer-stdunique_ptr",children:["Unique Pointer (",(0,a.jsx)(n.code,{children:"std::unique_ptr"}),")"]})}),"\n",(0,a.jsx)(n.h3,{id:"characteristics",children:(0,a.jsx)(n.a,{className:"heading-link",href:"#characteristics",children:"Characteristics"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Exclusive ownership"}),": Only one ",(0,a.jsx)(n.code,{children:"unique_ptr"})," can own a resource"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Move semantics"}),": Ownership can be transferred but not copied"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Zero overhead"}),": Same performance as raw pointers"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Custom deleters"}),": Support for custom cleanup functions"]}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"usage-examples",children:(0,a.jsx)(n.a,{className:"heading-link",href:"#usage-examples",children:"Usage Examples"})}),"\n",(0,a.jsx)(n.pre,{className:"language-cpp",children:(0,a.jsxs)(n.code,{className:"language-cpp code-highlight",children:[(0,a.jsxs)(n.span,{className:"code-line",children:[(0,a.jsx)(n.span,{className:"token comment",children:"// Creating unique_ptr"}),"\n"]}),(0,a.jsxs)(n.span,{className:"code-line",children:[(0,a.jsx)(n.span,{className:"token keyword",children:"auto"})," ptr ",(0,a.jsx)(n.span,{className:"token operator",children:"="})," std",(0,a.jsx)(n.span,{className:"token double-colon punctuation",children:"::"}),(0,a.jsxs)(n.span,{className:"token generic-function",children:[(0,a.jsx)(n.span,{className:"token function",children:"make_unique"}),(0,a.jsxs)(n.span,{className:"token generic class-name",children:[(0,a.jsx)(n.span,{className:"token operator",children:"<"}),"Widget",(0,a.jsx)(n.span,{className:"token operator",children:">"})]})]}),(0,a.jsx)(n.span,{className:"token punctuation",children:"("}),"args",(0,a.jsx)(n.span,{className:"token punctuation",children:")"}),(0,a.jsx)(n.span,{className:"token punctuation",children:";"}),"\n"]}),(0,a.jsx)(n.span,{className:"code-line",children:"\n"}),(0,a.jsxs)(n.span,{className:"code-line",children:[(0,a.jsx)(n.span,{className:"token comment",children:"// Transfer ownership"}),"\n"]}),(0,a.jsxs)(n.span,{className:"code-line",children:[(0,a.jsx)(n.span,{className:"token keyword",children:"auto"})," ptr2 ",(0,a.jsx)(n.span,{className:"token operator",children:"="})," std",(0,a.jsx)(n.span,{className:"token double-colon punctuation",children:"::"}),(0,a.jsx)(n.span,{className:"token function",children:"move"}),(0,a.jsx)(n.span,{className:"token punctuation",children:"("}),"ptr",(0,a.jsx)(n.span,{className:"token punctuation",children:")"}),(0,a.jsx)(n.span,{className:"token punctuation",children:";"})," ",(0,a.jsx)(n.span,{className:"token comment",children:"// ptr becomes nullptr"}),"\n"]}),(0,a.jsx)(n.span,{className:"code-line",children:"\n"}),(0,a.jsxs)(n.span,{className:"code-line",children:[(0,a.jsx)(n.span,{className:"token comment",children:"// Custom deleter"}),"\n"]}),(0,a.jsxs)(n.span,{className:"code-line",children:[(0,a.jsx)(n.span,{className:"token keyword",children:"auto"})," file ",(0,a.jsx)(n.span,{className:"token operator",children:"="})," std",(0,a.jsx)(n.span,{className:"token double-colon punctuation",children:"::"}),(0,a.jsxs)(n.span,{className:"token generic-function",children:[(0,a.jsx)(n.span,{className:"token function",children:"unique_ptr"}),(0,a.jsxs)(n.span,{className:"token generic class-name",children:[(0,a.jsx)(n.span,{className:"token operator",children:"<"}),"FILE",(0,a.jsx)(n.span,{className:"token punctuation",children:","})," ",(0,a.jsx)(n.span,{className:"token keyword",children:"decltype"}),(0,a.jsx)(n.span,{className:"token punctuation",children:"("}),(0,a.jsx)(n.span,{className:"token operator",children:"&"}),"fclose",(0,a.jsx)(n.span,{className:"token punctuation",children:")"}),(0,a.jsx)(n.span,{className:"token operator",children:">"})]})]}),(0,a.jsx)(n.span,{className:"token punctuation",children:"("}),"\n"]}),(0,a.jsxs)(n.span,{className:"code-line",children:[" ",(0,a.jsx)(n.span,{className:"token function",children:"fopen"}),(0,a.jsx)(n.span,{className:"token punctuation",children:"("}),(0,a.jsx)(n.span,{className:"token string",children:'"data.txt"'}),(0,a.jsx)(n.span,{className:"token punctuation",children:","})," ",(0,a.jsx)(n.span,{className:"token string",children:'"r"'}),(0,a.jsx)(n.span,{className:"token punctuation",children:")"}),(0,a.jsx)(n.span,{className:"token punctuation",children:","})," ",(0,a.jsx)(n.span,{className:"token operator",children:"&"}),"fclose\n"]}),(0,a.jsxs)(n.span,{className:"code-line",children:[(0,a.jsx)(n.span,{className:"token punctuation",children:")"}),(0,a.jsx)(n.span,{className:"token punctuation",children:";"}),"\n"]})]})}),"\n",(0,a.jsx)(n.h2,{id:"shared-pointer-stdshared_ptr",children:(0,a.jsxs)(n.a,{className:"heading-link",href:"#shared-pointer-stdshared_ptr",children:["Shared Pointer (",(0,a.jsx)(n.code,{children:"std::shared_ptr"}),")"]})}),"\n",(0,a.jsx)(n.h3,{id:"characteristics-1",children:(0,a.jsx)(n.a,{className:"heading-link",href:"#characteristics-1",children:"Characteristics"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Shared ownership"}),": Multiple pointers can own the same resource"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Reference counting"}),": Tracks how many pointers reference the object"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Thread-safe counting"}),": Reference count operations are atomic"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Automatic cleanup"}),": Object deleted when count reaches zero"]}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"reference-counting-process",children:(0,a.jsx)(n.a,{className:"heading-link",href:"#reference-counting-process",children:"Reference Counting Process"})}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:["Create ",(0,a.jsx)(n.code,{children:"shared_ptr"})," â count = 1"]}),"\n",(0,a.jsxs)(n.li,{children:["Copy ",(0,a.jsx)(n.code,{children:"shared_ptr"})," â count increments"]}),"\n",(0,a.jsxs)(n.li,{children:["Destroy ",(0,a.jsx)(n.code,{children:"shared_ptr"})," â count decrements"]}),"\n",(0,a.jsx)(n.li,{children:"Count reaches 0 â object deleted"}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"circular-reference-problem",children:(0,a.jsx)(n.a,{className:"heading-link",href:"#circular-reference-problem",children:"Circular Reference Problem"})}),"\n",(0,a.jsx)(n.pre,{className:"language-cpp",children:(0,a.jsxs)(n.code,{className:"language-cpp code-highlight",children:[(0,a.jsxs)(n.span,{className:"code-line",children:[(0,a.jsx)(n.span,{className:"token keyword",children:"struct"})," ",(0,a.jsx)(n.span,{className:"token class-name",children:"Node"})," ",(0,a.jsx)(n.span,{className:"token punctuation",children:"{"}),"\n"]}),(0,a.jsxs)(n.span,{className:"code-line",children:[" std",(0,a.jsx)(n.span,{className:"token double-colon punctuation",children:"::"}),"shared_ptr",(0,a.jsx)(n.span,{className:"token operator",children:"<"}),"Node",(0,a.jsx)(n.span,{className:"token operator",children:">"})," next",(0,a.jsx)(n.span,{className:"token punctuation",children:";"}),"\n"]}),(0,a.jsxs)(n.span,{className:"code-line",children:[" std",(0,a.jsx)(n.span,{className:"token double-colon punctuation",children:"::"}),"weak_ptr",(0,a.jsx)(n.span,{className:"token operator",children:"<"}),"Node",(0,a.jsx)(n.span,{className:"token operator",children:">"})," parent",(0,a.jsx)(n.span,{className:"token punctuation",children:";"})," ",(0,a.jsx)(n.span,{className:"token comment",children:"// Break cycle with weak_ptr"}),"\n"]}),(0,a.jsxs)(n.span,{className:"code-line",children:[(0,a.jsx)(n.span,{className:"token punctuation",children:"}"}),(0,a.jsx)(n.span,{className:"token punctuation",children:";"}),"\n"]})]})}),"\n",(0,a.jsx)(n.h2,{id:"weak-pointer-stdweak_ptr",children:(0,a.jsxs)(n.a,{className:"heading-link",href:"#weak-pointer-stdweak_ptr",children:["Weak Pointer (",(0,a.jsx)(n.code,{children:"std::weak_ptr"}),")"]})}),"\n",(0,a.jsx)(n.h3,{id:"characteristics-2",children:(0,a.jsx)(n.a,{className:"heading-link",href:"#characteristics-2",children:"Characteristics"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Non-owning"}),": Doesn't affect reference count"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Observer pattern"}),": Safely observe ",(0,a.jsx)(n.code,{children:"shared_ptr"})," objects"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Cycle breaking"}),": Prevents circular references"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Expiration checking"}),": Can detect if object still exists"]}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"usage-pattern",children:(0,a.jsx)(n.a,{className:"heading-link",href:"#usage-pattern",children:"Usage Pattern"})}),"\n",(0,a.jsx)(n.pre,{className:"language-cpp",children:(0,a.jsxs)(n.code,{className:"language-cpp code-highlight",children:[(0,a.jsxs)(n.span,{className:"code-line",children:["std",(0,a.jsx)(n.span,{className:"token double-colon punctuation",children:"::"}),"shared_ptr",(0,a.jsx)(n.span,{className:"token operator",children:"<"}),"Widget",(0,a.jsx)(n.span,{className:"token operator",children:">"})," shared ",(0,a.jsx)(n.span,{className:"token operator",children:"="})," std",(0,a.jsx)(n.span,{className:"token double-colon punctuation",children:"::"}),(0,a.jsxs)(n.span,{className:"token generic-function",children:[(0,a.jsx)(n.span,{className:"token function",children:"make_shared"}),(0,a.jsxs)(n.span,{className:"token generic class-name",children:[(0,a.jsx)(n.span,{className:"token operator",children:"<"}),"Widget",(0,a.jsx)(n.span,{className:"token operator",children:">"})]})]}),(0,a.jsx)(n.span,{className:"token punctuation",children:"("}),(0,a.jsx)(n.span,{className:"token punctuation",children:")"}),(0,a.jsx)(n.span,{className:"token punctuation",children:";"}),"\n"]}),(0,a.jsxs)(n.span,{className:"code-line",children:["std",(0,a.jsx)(n.span,{className:"token double-colon punctuation",children:"::"}),"weak_ptr",(0,a.jsx)(n.span,{className:"token operator",children:"<"}),"Widget",(0,a.jsx)(n.span,{className:"token operator",children:">"})," weak ",(0,a.jsx)(n.span,{className:"token operator",children:"="})," shared",(0,a.jsx)(n.span,{className:"token punctuation",children:";"}),"\n"]}),(0,a.jsx)(n.span,{className:"code-line",children:"\n"}),(0,a.jsxs)(n.span,{className:"code-line",children:[(0,a.jsx)(n.span,{className:"token keyword",children:"if"})," ",(0,a.jsx)(n.span,{className:"token punctuation",children:"("}),(0,a.jsx)(n.span,{className:"token keyword",children:"auto"})," locked ",(0,a.jsx)(n.span,{className:"token operator",children:"="})," weak",(0,a.jsx)(n.span,{className:"token punctuation",children:"."}),(0,a.jsx)(n.span,{className:"token function",children:"lock"}),(0,a.jsx)(n.span,{className:"token punctuation",children:"("}),(0,a.jsx)(n.span,{className:"token punctuation",children:")"}),(0,a.jsx)(n.span,{className:"token punctuation",children:")"})," ",(0,a.jsx)(n.span,{className:"token punctuation",children:"{"}),"\n"]}),(0,a.jsxs)(n.span,{className:"code-line",children:[" ",(0,a.jsx)(n.span,{className:"token comment",children:"// Use locked as shared_ptr"}),"\n"]}),(0,a.jsxs)(n.span,{className:"code-line",children:[" locked",(0,a.jsx)(n.span,{className:"token operator",children:"->"}),(0,a.jsx)(n.span,{className:"token function",children:"doSomething"}),(0,a.jsx)(n.span,{className:"token punctuation",children:"("}),(0,a.jsx)(n.span,{className:"token punctuation",children:")"}),(0,a.jsx)(n.span,{className:"token punctuation",children:";"}),"\n"]}),(0,a.jsxs)(n.span,{className:"code-line",children:[(0,a.jsx)(n.span,{className:"token punctuation",children:"}"})," ",(0,a.jsx)(n.span,{className:"token keyword",children:"else"})," ",(0,a.jsx)(n.span,{className:"token punctuation",children:"{"}),"\n"]}),(0,a.jsxs)(n.span,{className:"code-line",children:[" ",(0,a.jsx)(n.span,{className:"token comment",children:"// Object was destroyed"}),"\n"]}),(0,a.jsxs)(n.span,{className:"code-line",children:[(0,a.jsx)(n.span,{className:"token punctuation",children:"}"}),"\n"]})]})}),"\n",(0,a.jsx)(n.h2,{id:"best-practices",children:(0,a.jsx)(n.a,{className:"heading-link",href:"#best-practices",children:"Best Practices"})}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsxs)(n.strong,{children:["Prefer ",(0,a.jsx)(n.code,{children:"make_unique"})," and ",(0,a.jsx)(n.code,{children:"make_shared"})]})," for creation"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsxs)(n.strong,{children:["Use ",(0,a.jsx)(n.code,{children:"unique_ptr"})," by default"]}),", ",(0,a.jsx)(n.code,{children:"shared_ptr"})," when sharing needed"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Break cycles"})," with ",(0,a.jsx)(n.code,{children:"weak_ptr"})]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Pass raw pointers"})," to functions that don't affect ownership"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Return smart pointers"})," from factory functions"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Use custom deleters"})," for non-standard cleanup"]}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"performance-considerations",chi
1ldren:(0,a.jsx)(n.a,{className:"heading-link",href:"#performance-considerations",children:"Performance Considerations"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:(0,a.jsx)(n.code,{children:"unique_ptr"})}),": Zero overhead compared to raw pointers"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:(0,a.jsx)(n.code,{children:"shared_ptr"})}),": Small overhead for reference counting"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:(0,a.jsx)(n.code,{children:"weak_ptr"})}),": Minimal overhead, but requires lock() to access"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:(0,a.jsx)(n.code,{children:"make_shared"})}),": More efficient than ",(0,a.jsx)(n.code,{children:"shared_ptr(new T())"})]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"Smart pointers represent modern C++'s answer to memory management - providing safety without sacrificing performance."}),"\n",(0,a.jsx)(n.h2,{id:"related-concepts",children:(0,a.jsx)(n.a,{className:"heading-link",href:"#related-concepts",children:"Related concepts"})}),"\n",(0,a.jsx)(s,{})]})}void 0!==h&&h&&((void 0===h.wordCount||null===h.wordCount)&&(h.wordCount=370),h.readingTime||(h.readingTime="2 min"));let x=function(e={}){return(0,a.jsx)(p,Object.assign({},e,{children:(0,a.jsx)(m,e)}))}},83579:(e,n,s)=>{(window.__NEXT_P=window.__NEXT_P||[]).push(["/concepts/language-internals/smart-pointers",function(){return s(72696)}])}},e=>{e.O(0,[15863,82667,35674,90636,46593,38792],()=>e(e.s=83579)),_N_E=e.O()}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.