[{"data":1,"prerenderedAt":3126},["ShallowReactive",2],{"navigation":3,"\u002Fch10\u002Fsmart_pointer\u002Fshared_ptr":909,"\u002Fch10\u002Fsmart_pointer\u002Fshared_ptr-surround":3122},[4,36,56,96,230,270,414,457,508,583,649,685,767,864,900,904],{"title":5,"icon":6,"path":7,"stem":8,"children":9},"附录","i-lucide-bookmark","\u002Fappendix","appendix",[10,12,16,20,24,28,32],{"title":5,"path":7,"stem":11,"icon":6},"appendix\u002Findex",{"title":13,"path":14,"stem":15,"icon":6},"命令行界面","\u002Fappendix\u002Fcli","appendix\u002Fcli",{"title":17,"path":18,"stem":19,"icon":6},"代码风格","\u002Fappendix\u002Fcoding_style","appendix\u002Fcoding_style",{"title":21,"path":22,"stem":23,"icon":6},"关键字列表","\u002Fappendix\u002Fkeyword","appendix\u002Fkeyword",{"title":25,"path":26,"stem":27,"icon":6},"运算符优先级和结合方向","\u002Fappendix\u002Foperator","appendix\u002Foperator",{"title":29,"path":30,"stem":31,"icon":6},"预处理指令","\u002Fappendix\u002Fpreprocessor","appendix\u002Fpreprocessor",{"title":33,"path":34,"stem":35,"icon":6},"值类别","\u002Fappendix\u002Fvalue_category","appendix\u002Fvalue_category",{"title":37,"icon":38,"path":39,"stem":40,"children":41},"第〇章 基本概念","i-lucide-monitor","\u002Fch00","ch00",[42,44,48,52],{"title":37,"path":39,"stem":43,"icon":38},"ch00\u002Findex",{"title":45,"path":46,"stem":47,"icon":38},"计算机","\u002Fch00\u002Fcomputer","ch00\u002Fcomputer",{"title":49,"path":50,"stem":51,"icon":38},"编程","\u002Fch00\u002Fprogramming","ch00\u002Fprogramming",{"title":53,"path":54,"stem":55,"icon":38},"编程语言","\u002Fch00\u002Fprogramming_language","ch00\u002Fprogramming_language",{"title":57,"icon":58,"path":59,"stem":60,"children":61},"第一章 感性认识 C++ 程序","i-lucide-book-open","\u002Fch01","ch01",[62,64,68,72,76,80,84,88,92],{"title":57,"path":59,"stem":63,"icon":58},"ch01\u002Findex",{"title":65,"path":66,"stem":67,"icon":58},"赋值和分支","\u002Fch01\u002Fassignment_and_if","ch01\u002Fassignment_and_if",{"title":69,"path":70,"stem":71,"icon":58},"最麻烦的门槛","\u002Fch01\u002Fenvironment","ch01\u002Fenvironment",{"title":73,"path":74,"stem":75,"icon":58},"第一个 C++ 程序","\u002Fch01\u002Ffirst_program","ch01\u002Ffirst_program",{"title":77,"path":78,"stem":79,"icon":58},"输入","\u002Fch01\u002Finput","ch01\u002Finput",{"title":81,"path":82,"stem":83,"icon":58},"综合运用","\u002Fch01\u002Fintegrated_use","ch01\u002Fintegrated_use",{"title":85,"path":86,"stem":87,"icon":58},"循环","\u002Fch01\u002Floop","ch01\u002Floop",{"title":89,"path":90,"stem":91,"icon":58},"更多的输出","\u002Fch01\u002Fmore_output","ch01\u002Fmore_output",{"title":93,"path":94,"stem":95,"icon":58},"总结","\u002Fch01\u002Fsummary","ch01\u002Fsummary",{"title":97,"path":98,"stem":99,"children":100,"icon":102},"第二章 理性认识 C++ 程序","\u002Fch02","ch02\u002Findex",[101,103,149,188,227],{"title":97,"path":98,"stem":99,"icon":102},"i-lucide-code",{"title":104,"icon":105,"path":106,"stem":107,"children":108},"第 1 部分 数据成分","i-lucide-database","\u002Fch02\u002Fpart1","ch02\u002Fpart1\u002Findex",[109,110,114,118,122,126],{"title":104,"path":106,"stem":107,"icon":105},{"title":111,"path":112,"stem":113,"icon":105},"初识数组","\u002Fch02\u002Fpart1\u002Farray_glance","ch02\u002Fpart1\u002Farray_glance",{"title":115,"path":116,"stem":117,"icon":105},"常量","\u002Fch02\u002Fpart1\u002Fconstant","ch02\u002Fpart1\u002Fconstant",{"title":119,"path":120,"stem":121,"icon":105},"声明语句","\u002Fch02\u002Fpart1\u002Fdeclaration_statement","ch02\u002Fpart1\u002Fdeclaration_statement",{"title":123,"path":124,"stem":125,"icon":105},"只读变量","\u002Fch02\u002Fpart1\u002Freadonly_variable","ch02\u002Fpart1\u002Freadonly_variable",{"title":127,"icon":128,"path":129,"stem":130,"children":131},"类型系统","i-lucide-dna","\u002Fch02\u002Fpart1\u002Ftype_system","ch02\u002Fpart1\u002Ftype_system\u002Findex",[132,133,137,141,145],{"title":127,"path":129,"stem":130,"icon":128},{"title":134,"path":135,"stem":136,"icon":128},"布尔类型","\u002Fch02\u002Fpart1\u002Ftype_system\u002Fboolean_type","ch02\u002Fpart1\u002Ftype_system\u002Fboolean_type",{"title":138,"path":139,"stem":140,"icon":128},"字符类型","\u002Fch02\u002Fpart1\u002Ftype_system\u002Fcharacter_type","ch02\u002Fpart1\u002Ftype_system\u002Fcharacter_type",{"title":142,"path":143,"stem":144,"icon":128},"浮点类型","\u002Fch02\u002Fpart1\u002Ftype_system\u002Ffloat_type","ch02\u002Fpart1\u002Ftype_system\u002Ffloat_type",{"title":146,"path":147,"stem":148,"icon":128},"整型","\u002Fch02\u002Fpart1\u002Ftype_system\u002Finteger_type","ch02\u002Fpart1\u002Ftype_system\u002Finteger_type",{"title":150,"icon":151,"path":152,"stem":153,"children":154},"第 2 部分 运算成分","i-lucide-calculator","\u002Fch02\u002Fpart2","ch02\u002Fpart2\u002Findex",[155,156,160,164,168,172,176,180,184],{"title":150,"path":152,"stem":153,"icon":151},{"title":157,"path":158,"stem":159,"icon":151},"算术运算符","\u002Fch02\u002Fpart2\u002Farithmetic_operator","ch02\u002Fpart2\u002Farithmetic_operator",{"title":161,"path":162,"stem":163,"icon":151},"赋值运算符","\u002Fch02\u002Fpart2\u002Fassignment_operator","ch02\u002Fpart2\u002Fassignment_operator",{"title":165,"path":166,"stem":167,"icon":151},"位运算符（选读）","\u002Fch02\u002Fpart2\u002Fbit_operator","ch02\u002Fpart2\u002Fbit_operator",{"title":169,"path":170,"stem":171,"icon":151},"关系运算符","\u002Fch02\u002Fpart2\u002Fcomparison_operator","ch02\u002Fpart2\u002Fcomparison_operator",{"title":173,"path":174,"stem":175,"icon":151},"算术类型隐式转换","\u002Fch02\u002Fpart2\u002Fimplicit_conversion","ch02\u002Fpart2\u002Fimplicit_conversion",{"title":177,"path":178,"stem":179,"icon":151},"自增减运算符","\u002Fch02\u002Fpart2\u002Fincdec_operator","ch02\u002Fpart2\u002Fincdec_operator",{"title":181,"path":182,"stem":183,"icon":151},"逻辑运算符","\u002Fch02\u002Fpart2\u002Flogical_operator","ch02\u002Fpart2\u002Flogical_operator",{"title":185,"path":186,"stem":187,"icon":151},"其它常用运算符","\u002Fch02\u002Fpart2\u002Fother_operator","ch02\u002Fpart2\u002Fother_operator",{"title":189,"icon":190,"path":191,"stem":192,"children":193},"第 3 部分 控制成分","i-lucide-git-branch","\u002Fch02\u002Fpart3","ch02\u002Fpart3\u002Findex",[194,195,199,203,207,211,215,219,223],{"title":189,"path":191,"stem":192,"icon":190},{"title":196,"path":197,"stem":198,"icon":190},"复合语句","\u002Fch02\u002Fpart3\u002Fcompound_statement","ch02\u002Fpart3\u002Fcompound_statement",{"title":200,"path":201,"stem":202,"icon":190},"for 语句","\u002Fch02\u002Fpart3\u002Ffor_statement","ch02\u002Fpart3\u002Ffor_statement",{"title":204,"path":205,"stem":206,"icon":190},"if 语句","\u002Fch02\u002Fpart3\u002Fif_statement","ch02\u002Fpart3\u002Fif_statement",{"title":208,"path":209,"stem":210,"icon":190},"跳转语句","\u002Fch02\u002Fpart3\u002Fjump_statement","ch02\u002Fpart3\u002Fjump_statement",{"title":212,"path":213,"stem":214,"icon":190},"空语句","\u002Fch02\u002Fpart3\u002Fnull_statement","ch02\u002Fpart3\u002Fnull_statement",{"title":216,"path":217,"stem":218,"icon":190},"作用域","\u002Fch02\u002Fpart3\u002Fscope","ch02\u002Fpart3\u002Fscope",{"title":220,"path":221,"stem":222,"icon":190},"switch 语句","\u002Fch02\u002Fpart3\u002Fswitch_statement","ch02\u002Fpart3\u002Fswitch_statement",{"title":224,"path":225,"stem":226,"icon":190},"while 语句","\u002Fch02\u002Fpart3\u002Fwhile_statement","ch02\u002Fpart3\u002Fwhile_statement",{"title":93,"path":228,"stem":229,"icon":102},"\u002Fch02\u002Fsummary","ch02\u002Fsummary",{"title":231,"icon":232,"path":233,"stem":234,"children":235},"第三章 过程式编程","i-lucide-function-square","\u002Fch03","ch03",[236,239,243,247,251,255,259,263,267],{"title":231,"path":233,"stem":237,"icon":238},"ch03\u002Findex","i-lucide-square-function",{"title":240,"path":241,"stem":242,"icon":232},"函数","\u002Fch03\u002Ffunction","ch03\u002Ffunction",{"title":244,"path":245,"stem":246,"icon":232},"函数的定义、声明和调用","\u002Fch03\u002Ffunction_definition","ch03\u002Ffunction_definition",{"title":248,"path":249,"stem":250,"icon":232},"函数的执行","\u002Fch03\u002Ffunction_execution","ch03\u002Ffunction_execution",{"title":252,"path":253,"stem":254,"icon":232},"初识函数","\u002Fch03\u002Ffunction_glance","ch03\u002Ffunction_glance",{"title":256,"path":257,"stem":258,"icon":232},"递归","\u002Fch03\u002Frecursion","ch03\u002Frecursion",{"title":260,"path":261,"stem":262,"icon":232},"重新认识 C++ 程序","\u002Fch03\u002Freview_cpp","ch03\u002Freview_cpp",{"title":264,"path":265,"stem":266,"icon":232},"再谈作用域","\u002Fch03\u002Fscope_again","ch03\u002Fscope_again",{"title":93,"path":268,"stem":269,"icon":232},"\u002Fch03\u002Fsummary","ch03\u002Fsummary",{"title":271,"icon":272,"path":273,"stem":274,"children":275},"第四章 POD 类型与结构","i-lucide-layers","\u002Fch04","ch04",[276,278,301,316,320,338,365,392,407,410],{"title":271,"path":273,"stem":277,"icon":272},"ch04\u002Findex",{"title":279,"icon":280,"path":281,"stem":282,"children":283},"数组","i-lucide-grid","\u002Fch04\u002Farray","ch04\u002Farray\u002Findex",[284,285,289,293,297],{"title":279,"path":281,"stem":282,"icon":280},{"title":286,"path":287,"stem":288,"icon":280},"二维数组","\u002Fch04\u002Farray\u002F2d_array","ch04\u002Farray\u002F2d_array",{"title":290,"path":291,"stem":292,"icon":280},"数组的定义和初始化","\u002Fch04\u002Farray\u002Farray_init","ch04\u002Farray\u002Farray_init",{"title":294,"path":295,"stem":296,"icon":280},"数组的用途","\u002Fch04\u002Farray\u002Farray_usage","ch04\u002Farray\u002Farray_usage",{"title":298,"path":299,"stem":300,"icon":280},"C 风格字符串","\u002Fch04\u002Farray\u002Fc_string","ch04\u002Farray\u002Fc_string",{"title":302,"icon":303,"path":304,"stem":305,"children":306},"迁移到 C 语言","i-lucide-arrow-right-left","\u002Fch04\u002Fcompare_with_c","ch04\u002Fcompare_with_c\u002Findex",[307,308,312],{"title":302,"path":304,"stem":305,"icon":303},{"title":309,"path":310,"stem":311,"icon":303},"需要注意的 C 特性","\u002Fch04\u002Fcompare_with_c\u002Fc_feature","ch04\u002Fcompare_with_c\u002Fc_feature",{"title":313,"path":314,"stem":315,"icon":303},"C 输入输出","\u002Fch04\u002Fcompare_with_c\u002Fc_io","ch04\u002Fcompare_with_c\u002Fc_io",{"title":317,"path":318,"stem":319,"icon":272},"枚举","\u002Fch04\u002Fenum","ch04\u002Fenum",{"title":321,"path":322,"stem":323,"children":324,"icon":326},"输入输出成分","\u002Fch04\u002Fio","ch04\u002Fio\u002Findex",[325,327,330,334],{"title":321,"path":322,"stem":323,"icon":326},"i-lucide-terminal",{"title":77,"path":328,"stem":329,"icon":326},"\u002Fch04\u002Fio\u002Finput","ch04\u002Fio\u002Finput",{"title":331,"path":332,"stem":333,"icon":326},"输入失败状态","\u002Fch04\u002Fio\u002Finput_fail","ch04\u002Fio\u002Finput_fail",{"title":335,"path":336,"stem":337,"icon":326},"输出","\u002Fch04\u002Fio\u002Foutput","ch04\u002Fio\u002Foutput",{"title":339,"icon":340,"path":341,"stem":342,"children":343},"链表","i-lucide-list","\u002Fch04\u002Flist","ch04\u002Flist\u002Findex",[344,345,349,353,357,361],{"title":339,"path":341,"stem":342,"icon":340},{"title":346,"path":347,"stem":348,"icon":340},"new[] 和 delete[]","\u002Fch04\u002Flist\u002Farr_new_del","ch04\u002Flist\u002Farr_new_del",{"title":350,"path":351,"stem":352,"icon":340},"链表的增删","\u002Fch04\u002Flist\u002Flist_add_del","ch04\u002Flist\u002Flist_add_del",{"title":354,"path":355,"stem":356,"icon":340},"链表的构建","\u002Fch04\u002Flist\u002Flist_construct","ch04\u002Flist\u002Flist_construct",{"title":358,"path":359,"stem":360,"icon":340},"安全性","\u002Fch04\u002Flist\u002Fsafety","ch04\u002Flist\u002Fsafety",{"title":362,"path":363,"stem":364,"icon":340},"存储期","\u002Fch04\u002Flist\u002Fstorage_duration","ch04\u002Flist\u002Fstorage_duration",{"title":366,"path":367,"stem":368,"children":369,"icon":371},"指针","\u002Fch04\u002Fpointer","ch04\u002Fpointer\u002Findex",[370,372,376,380,384,388],{"title":366,"path":367,"stem":368,"icon":371},"i-lucide-dot",{"title":373,"path":374,"stem":375,"icon":371},"何为指针","\u002Fch04\u002Fpointer\u002Fpointer","ch04\u002Fpointer\u002Fpointer",{"title":377,"path":378,"stem":379,"icon":371},"指针和数组","\u002Fch04\u002Fpointer\u002Fpointer_and_array","ch04\u002Fpointer\u002Fpointer_and_array",{"title":381,"path":382,"stem":383,"icon":371},"指针的定义 Ⅰ","\u002Fch04\u002Fpointer\u002Fpointer_def","ch04\u002Fpointer\u002Fpointer_def",{"title":385,"path":386,"stem":387,"icon":371},"指针的定义 Ⅱ","\u002Fch04\u002Fpointer\u002Fpointer_def_2","ch04\u002Fpointer\u002Fpointer_def_2",{"title":389,"path":390,"stem":391,"icon":371},"指针的简单使用","\u002Fch04\u002Fpointer\u002Fpointer_usage","ch04\u002Fpointer\u002Fpointer_usage",{"title":393,"path":394,"stem":395,"children":396,"icon":398},"结构体","\u002Fch04\u002Fstruct","ch04\u002Fstruct\u002Findex",[397,399,403],{"title":393,"path":394,"stem":395,"icon":398},"i-lucide-box",{"title":400,"path":401,"stem":402,"icon":398},"结构体的定义","\u002Fch04\u002Fstruct\u002Fstruct_def","ch04\u002Fstruct\u002Fstruct_def",{"title":404,"path":405,"stem":406,"icon":398},"结构体的使用","\u002Fch04\u002Fstruct\u002Fstruct_usage","ch04\u002Fstruct\u002Fstruct_usage",{"title":93,"path":408,"stem":409,"icon":272},"\u002Fch04\u002Fsummary","ch04\u002Fsummary",{"title":411,"path":412,"stem":413,"icon":272},"联合体","\u002Fch04\u002Funion","ch04\u002Funion",{"title":415,"icon":416,"path":417,"stem":418,"children":419},"第五章 初探面向对象","i-lucide-copy","\u002Fch05","ch05",[420,422,426,430,434,438,442,446,450,454],{"title":415,"path":417,"stem":421,"icon":416},"ch05\u002Findex",{"title":423,"path":424,"stem":425,"icon":416},"构造函数","\u002Fch05\u002Fconstructor","ch05\u002Fconstructor",{"title":427,"path":428,"stem":429,"icon":416},"复制构造函数","\u002Fch05\u002Fcopy_constructor","ch05\u002Fcopy_constructor",{"title":431,"path":432,"stem":433,"icon":416},"预置构造函数","\u002Fch05\u002Fdefaulted_constructor","ch05\u002Fdefaulted_constructor",{"title":435,"path":436,"stem":437,"icon":416},"例子：简单的字符串","\u002Fch05\u002Feasy_string","ch05\u002Feasy_string",{"title":439,"path":440,"stem":441,"icon":416},"收尾工作","\u002Fch05\u002Fmisc","ch05\u002Fmisc",{"title":443,"path":444,"stem":445,"icon":416},"重载","\u002Fch05\u002Foverload","ch05\u002Foverload",{"title":447,"path":448,"stem":449,"icon":416},"引用","\u002Fch05\u002Freference","ch05\u002Freference",{"title":451,"path":452,"stem":453,"icon":416},"浅复制与深复制","\u002Fch05\u002Fshallow_deep_copy","ch05\u002Fshallow_deep_copy",{"title":93,"path":455,"stem":456,"icon":416},"\u002Fch05\u002Fsummary","ch05\u002Fsummary",{"title":458,"icon":459,"path":460,"stem":461,"children":462},"第六章 运算符重载","i-lucide-component","\u002Fch06","ch06",[463,465,469,473,477,481,485,489,493,497,501,504],{"title":458,"path":460,"stem":464,"icon":459},"ch06\u002Findex",{"title":466,"path":467,"stem":468,"icon":459},"赋值运算符重载","\u002Fch06\u002Fassignment_overload","ch06\u002Fassignment_overload",{"title":470,"path":471,"stem":472,"icon":459},"赋值与初始化","\u002Fch06\u002Fassignment_vs_construct","ch06\u002Fassignment_vs_construct",{"title":474,"path":475,"stem":476,"icon":459},"类型转换重载","\u002Fch06\u002Fcast_overload","ch06\u002Fcast_overload",{"title":478,"path":479,"stem":480,"icon":459},"只读成员函数","\u002Fch06\u002Fconst_member_function","ch06\u002Fconst_member_function",{"title":482,"path":483,"stem":484,"icon":459},"友元","\u002Fch06\u002Ffriend","ch06\u002Ffriend",{"title":486,"path":487,"stem":488,"icon":459},"类外定义成员函数","\u002Fch06\u002Fnoninline_member_function","ch06\u002Fnoninline_member_function",{"title":490,"path":491,"stem":492,"icon":459},"非成员的运算符重载","\u002Fch06\u002Fnonmember_operator","ch06\u002Fnonmember_operator",{"title":494,"path":495,"stem":496,"icon":459},"特殊运算符重载","\u002Fch06\u002Fspecial_operator_overload","ch06\u002Fspecial_operator_overload",{"title":498,"path":499,"stem":500,"icon":459},"静态成员","\u002Fch06\u002Fstatic_member","ch06\u002Fstatic_member",{"title":93,"path":502,"stem":503,"icon":459},"\u002Fch06\u002Fsummary","ch06\u002Fsummary",{"title":505,"path":506,"stem":507,"icon":459},"`this` 指针","\u002Fch06\u002Fthis","ch06\u002Fthis",{"title":509,"path":510,"stem":511,"children":512,"icon":190},"第七章 继承与多态","\u002Fch07","ch07\u002Findex",[513,514,541,545,549,580],{"title":509,"path":510,"stem":511,"icon":190},{"title":515,"icon":516,"path":517,"stem":518,"children":519},"继承关系","i-lucide-share","\u002Fch07\u002Finheritance","ch07\u002Finheritance\u002Findex",[520,521,525,529,533,537],{"title":515,"path":517,"stem":518,"icon":516},{"title":522,"path":523,"stem":524,"icon":516},"关于成员名","\u002Fch07\u002Finheritance\u002Fabout_member_name","ch07\u002Finheritance\u002Fabout_member_name",{"title":526,"path":527,"stem":528,"icon":516},"派生类的构造","\u002Fch07\u002Finheritance\u002Fderived_constructor","ch07\u002Finheritance\u002Fderived_constructor",{"title":530,"path":531,"stem":532,"icon":516},"继承中的隐式转换","\u002Fch07\u002Finheritance\u002Fimplicit_cast_in_inheritance","ch07\u002Finheritance\u002Fimplicit_cast_in_inheritance",{"title":534,"path":535,"stem":536,"icon":516},"其它小问题","\u002Fch07\u002Finheritance\u002Fmisc","ch07\u002Finheritance\u002Fmisc",{"title":538,"path":539,"stem":540,"icon":516},"保护成员","\u002Fch07\u002Finheritance\u002Fprotected_member","ch07\u002Finheritance\u002Fprotected_member",{"title":542,"path":543,"stem":544,"icon":190},"多重继承","\u002Fch07\u002Fmi","ch07\u002Fmi",{"title":546,"path":547,"stem":548,"icon":190},"简单的对象关系","\u002Fch07\u002Fobject_relationships","ch07\u002Fobject_relationships",{"title":550,"icon":551,"path":552,"stem":553,"children":554},"多态","i-lucide-refresh","\u002Fch07\u002Fpolymorphism","ch07\u002Fpolymorphism\u002Findex",[555,556,560,564,568,572,576],{"title":550,"path":552,"stem":553,"icon":551},{"title":557,"path":558,"stem":559,"icon":551},"抽象类","\u002Fch07\u002Fpolymorphism\u002Fabstract_class","ch07\u002Fpolymorphism\u002Fabstract_class",{"title":561,"path":562,"stem":563,"icon":551},"C++ 风格类型转换","\u002Fch07\u002Fpolymorphism\u002Fcpp_cast","ch07\u002Fpolymorphism\u002Fcpp_cast",{"title":565,"path":566,"stem":567,"icon":551},"`override` 与 `final`","\u002Fch07\u002Fpolymorphism\u002Foverride_and_final","ch07\u002Fpolymorphism\u002Foverride_and_final",{"title":569,"path":570,"stem":571,"icon":551},"RTTI","\u002Fch07\u002Fpolymorphism\u002Frtti","ch07\u002Fpolymorphism\u002Frtti",{"title":573,"path":574,"stem":575,"icon":551},"虚析构函数","\u002Fch07\u002Fpolymorphism\u002Fvirtual_destructor","ch07\u002Fpolymorphism\u002Fvirtual_destructor",{"title":577,"path":578,"stem":579,"icon":551},"虚函数","\u002Fch07\u002Fpolymorphism\u002Fvirtual_function","ch07\u002Fpolymorphism\u002Fvirtual_function",{"title":93,"path":581,"stem":582,"icon":190},"\u002Fch07\u002Fsummary","ch07\u002Fsummary",{"title":584,"icon":585,"path":586,"stem":587,"children":588},"第八章 模板基础","i-lucide-layout-template","\u002Fch08","ch08",[589,591,595,599,603,607,646],{"title":584,"path":586,"stem":590,"icon":585},"ch08\u002Findex",{"title":592,"path":593,"stem":594,"icon":585},"类模板","\u002Fch08\u002Fclass_template","ch08\u002Fclass_template",{"title":596,"path":597,"stem":598,"icon":585},"默认实参","\u002Fch08\u002Fdefault_argument","ch08\u002Fdefault_argument",{"title":600,"path":601,"stem":602,"icon":585},"函数模板","\u002Fch08\u002Ffunction_template","ch08\u002Ffunction_template",{"title":604,"path":605,"stem":606,"icon":585},"非类型模板参数","\u002Fch08\u002Fnontype_template_param","ch08\u002Fnontype_template_param",{"title":608,"icon":609,"path":610,"stem":611,"children":612},"STL 容器和迭代器","i-lucide-container","\u002Fch08\u002Fstl_containers","ch08\u002Fstl_containers\u002Findex",[613,614,618,622,626,630,634,638,642],{"title":608,"path":610,"stem":611,"icon":609},{"title":615,"path":616,"stem":617,"icon":609},"容器适配器","\u002Fch08\u002Fstl_containers\u002Fadaptors","ch08\u002Fstl_containers\u002Fadaptors",{"title":619,"path":620,"stem":621,"icon":609},"迭代器的概念","\u002Fch08\u002Fstl_containers\u002Fiterator_concept","ch08\u002Fstl_containers\u002Fiterator_concept",{"title":623,"path":624,"stem":625,"icon":609},"初识迭代器","\u002Fch08\u002Fstl_containers\u002Fiterator_glance","ch08\u002Fstl_containers\u002Fiterator_glance",{"title":627,"path":628,"stem":629,"icon":609},"迭代器的用途","\u002Fch08\u002Fstl_containers\u002Fiterator_usage","ch08\u002Fstl_containers\u002Fiterator_usage",{"title":631,"path":632,"stem":633,"icon":609},"`std::map`","\u002Fch08\u002Fstl_containers\u002Fmap","ch08\u002Fstl_containers\u002Fmap",{"title":635,"path":636,"stem":637,"icon":609},"其它顺序容器","\u002Fch08\u002Fstl_containers\u002Fother_sequence","ch08\u002Fstl_containers\u002Fother_sequence",{"title":639,"path":640,"stem":641,"icon":609},"`std::set`","\u002Fch08\u002Fstl_containers\u002Fset","ch08\u002Fstl_containers\u002Fset",{"title":643,"path":644,"stem":645,"icon":609},"`std::vector`","\u002Fch08\u002Fstl_containers\u002Fvector","ch08\u002Fstl_containers\u002Fvector",{"title":93,"path":647,"stem":648,"icon":585},"\u002Fch08\u002Fsummary","ch08\u002Fsummary",{"title":650,"icon":651,"path":652,"stem":653,"children":654},"第九章 链接","i-lucide-link","\u002Fch09","ch09",[655,657,661,665,669,673,677,681],{"title":650,"path":652,"stem":656,"icon":651},"ch09\u002Findex",{"title":658,"path":659,"stem":660,"icon":651},"C 中的链接","\u002Fch09\u002Fc_linking","ch09\u002Fc_linking",{"title":662,"path":663,"stem":664,"icon":651},"多文件编译实践","\u002Fch09\u002Fcompile_multiple_files","ch09\u002Fcompile_multiple_files",{"title":666,"path":667,"stem":668,"icon":651},"模板中的友元","\u002Fch09\u002Ffriend_in_template","ch09\u002Ffriend_in_template",{"title":670,"path":671,"stem":672,"icon":651},"内联","\u002Fch09\u002Finline","ch09\u002Finline",{"title":674,"path":675,"stem":676,"icon":651},"单一定义原则","\u002Fch09\u002Fodr","ch09\u002Fodr",{"title":678,"path":679,"stem":680,"icon":651},"符号和连接","\u002Fch09\u002Fsymbol_and_linkage","ch09\u002Fsymbol_and_linkage",{"title":682,"path":683,"stem":684,"icon":651},"模板的链接","\u002Fch09\u002Ftemplate_linking","ch09\u002Ftemplate_linking",{"title":686,"icon":687,"path":688,"stem":689,"children":690},"第十章 常用库介绍 \u003CBadge type=\"warning\" text=\"TBC\" \u002F>","i-lucide-hard-drive","\u002Fch10","ch10",[691,694,717,732,736,740],{"title":692,"path":688,"stem":693,"icon":687},"第十章 常用库介绍","ch10\u002Findex",{"title":695,"icon":696,"path":697,"stem":698,"children":699},"代数数据类型","i-lucide-shapes","\u002Fch10\u002Fadt","ch10\u002Fadt\u002Findex",[700,701,705,709,713],{"title":695,"path":697,"stem":698,"icon":696},{"title":702,"path":703,"stem":704,"icon":696},"顶类型 `std::any`","\u002Fch10\u002Fadt\u002Fany","ch10\u002Fadt\u002Fany",{"title":706,"path":707,"stem":708,"icon":696},"底类型","\u002Fch10\u002Fadt\u002Fnoreturn","ch10\u002Fadt\u002Fnoreturn",{"title":710,"path":711,"stem":712,"icon":696},"通用积类型 `std::tuple`","\u002Fch10\u002Fadt\u002Ftuple","ch10\u002Fadt\u002Ftuple",{"title":714,"path":715,"stem":716,"icon":696},"通用和类型 `std::variant`","\u002Fch10\u002Fadt\u002Fvariant","ch10\u002Fadt\u002Fvariant",{"title":718,"icon":719,"path":720,"stem":721,"children":722},"文件读写","i-lucide-file-text","\u002Fch10\u002Ffile_io","ch10\u002Ffile_io\u002Findex",[723,724,728],{"title":718,"path":720,"stem":721,"icon":719},{"title":725,"path":726,"stem":727,"icon":719},"C 风格输入输出","\u002Fch10\u002Ffile_io\u002Fc_io","ch10\u002Ffile_io\u002Fc_io",{"title":729,"path":730,"stem":731,"icon":719},"流式输入输出","\u002Fch10\u002Ffile_io\u002Fstream","ch10\u002Ffile_io\u002Fstream",{"title":733,"path":734,"stem":735,"icon":687},"文件系统","\u002Fch10\u002Ffilesystem","ch10\u002Ffilesystem",{"title":737,"path":738,"stem":739,"icon":687},"伪随机数生成","\u002Fch10\u002Frandom","ch10\u002Frandom",{"title":741,"path":742,"stem":743,"children":744,"icon":746},"移动语义与智能指针","\u002Fch10\u002Fsmart_pointer","ch10\u002Fsmart_pointer\u002Findex",[745,747,751,755,759,763],{"title":741,"path":742,"stem":743,"icon":746},"i-lucide-pointer",{"title":748,"path":749,"stem":750,"icon":746},"`std::move` 与转发引用","\u002Fch10\u002Fsmart_pointer\u002Fmove_and_forward","ch10\u002Fsmart_pointer\u002Fmove_and_forward",{"title":752,"path":753,"stem":754,"icon":746},"所有权","\u002Fch10\u002Fsmart_pointer\u002Fownership","ch10\u002Fsmart_pointer\u002Fownership",{"title":756,"path":757,"stem":758,"icon":746},"右值引用","\u002Fch10\u002Fsmart_pointer\u002Frvalue_reference","ch10\u002Fsmart_pointer\u002Frvalue_reference",{"title":760,"path":761,"stem":762,"icon":746},"`std::shared_ptr`","\u002Fch10\u002Fsmart_pointer\u002Fshared_ptr","ch10\u002Fsmart_pointer\u002Fshared_ptr",{"title":764,"path":765,"stem":766,"icon":746},"特殊成员函数","\u002Fch10\u002Fsmart_pointer\u002Fspecial_member_function","ch10\u002Fsmart_pointer\u002Fspecial_member_function",{"title":768,"icon":769,"path":770,"stem":771,"children":772},"第十一章 函数式编程","i-lucide-sparkles","\u002Fch11","ch11",[773,775,794,821,825],{"title":768,"path":770,"stem":774,"icon":769},"ch11\u002Findex",{"title":776,"icon":777,"path":778,"stem":779,"children":780},"语法进阶","i-lucide-graduation-cap","\u002Fch11\u002Fadvanced","ch11\u002Fadvanced\u002Findex",[781,782,786,790],{"title":776,"path":778,"stem":779,"icon":777},{"title":783,"path":784,"stem":785,"icon":777},"实参依赖查找","\u002Fch11\u002Fadvanced\u002Fadl","ch11\u002Fadvanced\u002Fadl",{"title":787,"path":788,"stem":789,"icon":777},"可调用","\u002Fch11\u002Fadvanced\u002Fcallable","ch11\u002Fadvanced\u002Fcallable",{"title":791,"path":792,"stem":793,"icon":777},"预置比较","\u002Fch11\u002Fadvanced\u002Fdefaulted_compare","ch11\u002Fadvanced\u002Fdefaulted_compare",{"title":795,"icon":796,"path":797,"stem":798,"children":799},"语法基础","i-lucide-book-text","\u002Fch11\u002Fgrammar","ch11\u002Fgrammar\u002Findex",[800,801,805,809,813,817],{"title":795,"path":797,"stem":798,"icon":796},{"title":802,"path":803,"stem":804,"icon":796},"闭包","\u002Fch11\u002Fgrammar\u002Fclosure","ch11\u002Fgrammar\u002Fclosure",{"title":806,"path":807,"stem":808,"icon":796},"函数也即对象","\u002Fch11\u002Fgrammar\u002Ffunction_as_object","ch11\u002Fgrammar\u002Ffunction_as_object",{"title":810,"path":811,"stem":812,"icon":796},"高阶函数","\u002Fch11\u002Fgrammar\u002Fhigher_order_function","ch11\u002Fgrammar\u002Fhigher_order_function",{"title":814,"path":815,"stem":816,"icon":796},"Lambda 表达式","\u002Fch11\u002Fgrammar\u002Flambda","ch11\u002Fgrammar\u002Flambda",{"title":818,"path":819,"stem":820,"icon":796},"Lambda 表达式捕获","\u002Fch11\u002Fgrammar\u002Flambda_capture","ch11\u002Fgrammar\u002Flambda_capture",{"title":822,"path":823,"stem":824,"icon":769},"`std::sort`","\u002Fch11\u002Fstd_sort","ch11\u002Fstd_sort",{"title":826,"icon":827,"path":828,"stem":829,"children":830},"STL 算法","i-lucide-sort-asc","\u002Fch11\u002Fstl_algorithms","ch11\u002Fstl_algorithms\u002Findex",[831,832,836,840,844,848,852,856,860],{"title":826,"path":828,"stem":829,"icon":827},{"title":833,"path":834,"stem":835,"icon":827},"迁移到 STLv1","\u002Fch11\u002Fstl_algorithms\u002Fcompare_with_legacy","ch11\u002Fstl_algorithms\u002Fcompare_with_legacy",{"title":837,"path":838,"stem":839,"icon":827},"复制","\u002Fch11\u002Fstl_algorithms\u002Fcopy","ch11\u002Fstl_algorithms\u002Fcopy",{"title":841,"path":842,"stem":843,"icon":827},"筛选","\u002Fch11\u002Fstl_algorithms\u002Ffilter","ch11\u002Fstl_algorithms\u002Ffilter",{"title":845,"path":846,"stem":847,"icon":827},"其它算法","\u002Fch11\u002Fstl_algorithms\u002Fothers","ch11\u002Fstl_algorithms\u002Fothers",{"title":849,"path":850,"stem":851,"icon":827},"初识范围","\u002Fch11\u002Fstl_algorithms\u002Frange","ch11\u002Fstl_algorithms\u002Frange",{"title":853,"path":854,"stem":855,"icon":827},"归约","\u002Fch11\u002Fstl_algorithms\u002Freduce","ch11\u002Fstl_algorithms\u002Freduce",{"title":857,"path":858,"stem":859,"icon":827},"排序","\u002Fch11\u002Fstl_algorithms\u002Fsort","ch11\u002Fstl_algorithms\u002Fsort",{"title":861,"path":862,"stem":863,"icon":827},"变换","\u002Fch11\u002Fstl_algorithms\u002Ftransform","ch11\u002Fstl_algorithms\u002Ftransform",{"title":865,"icon":866,"path":867,"stem":868,"children":869},"第十二章 模板","i-lucide-git-fork","\u002Fch12","ch12",[870,873,877,881,885],{"title":871,"path":867,"stem":872,"icon":866},"第十二章 模板进阶","ch12\u002Findex",{"title":874,"path":875,"stem":876},"C++20 概念","\u002Fch12\u002Fconcepts","ch12\u002Fconcepts",{"title":878,"path":879,"stem":880},"模板元编程","\u002Fch12\u002Fmetaprogramming","ch12\u002Fmetaprogramming",{"title":882,"path":883,"stem":884},"模板特化与偏特化","\u002Fch12\u002Fspecialization","ch12\u002Fspecialization",{"title":886,"icon":887,"path":888,"stem":889,"children":890},"静态派发","i-lucide-route","\u002Fch12\u002Fstatic_dispatch","ch12\u002Fstatic_dispatch\u002Findex",[891,892,896],{"title":886,"path":888,"stem":889},{"title":893,"path":894,"stem":895},"定制点","\u002Fch12\u002Fstatic_dispatch\u002Fcustomize_point","ch12\u002Fstatic_dispatch\u002Fcustomize_point",{"title":897,"path":898,"stem":899},"类型擦除","\u002Fch12\u002Fstatic_dispatch\u002Ftype_erasure","ch12\u002Fstatic_dispatch\u002Ftype_erasure",{"title":901,"path":902,"stem":903,"icon":6},"后记","\u002Fpostscript","postscript",{"title":905,"path":906,"stem":907,"icon":908},"技术信息","\u002Ftechnical_info","technical_info","i-lucide-info",{"id":910,"title":760,"body":911,"description":3115,"extension":3116,"links":3117,"meta":3118,"navigation":3119,"path":761,"seo":3120,"stem":762,"__hash__":3121},"docs\u002Fch10\u002Fsmart_pointer\u002Fshared_ptr.md",{"type":912,"value":913,"toc":3112},"minimark",[914,922,928,1073,1086,1218,1236,1240,1253,1388,1391,1633,1636,1965,1968,2389,2402,2414,2438,2456,2491,2497,3082,3088,3108],[915,916,918],"h1",{"id":917},"stdshared_ptr",[919,920,921],"code",{},"std::shared_ptr",[923,924,925,927],"p",{},[919,926,921],{}," 是具有共享所有权的智能指针。与独占所有权不同，共享所有权指有多个对象持有同一资源的所有权。比如下面的例子中：",[929,930,935],"pre",{"className":931,"code":932,"language":933,"meta":934,"style":934},"language-cpp shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","#include \u003Cmemory>\n\nint main() {\n    std::shared_ptr\u003Cint> p = std::make_shared\u003Cint>(42);\n    std::shared_ptr\u003Cint> q = p; \u002F\u002F 也可用 auto 占位符声明\n    \u002F\u002F [...]\n}\n","cpp","",[919,936,937,957,964,981,1031,1061,1067],{"__ignoreMap":934},[938,939,942,946,950,954],"span",{"class":940,"line":941},"line",1,[938,943,945],{"class":944},"s7zQu","#include",[938,947,949],{"class":948},"sMK4o"," \u003C",[938,951,953],{"class":952},"sfazB","memory",[938,955,956],{"class":948},">\n",[938,958,960],{"class":940,"line":959},2,[938,961,963],{"emptyLinePlaceholder":962},true,"\n",[938,965,967,971,975,978],{"class":940,"line":966},3,[938,968,970],{"class":969},"spNyl","int",[938,972,974],{"class":973},"s2Zo4"," main",[938,976,977],{"class":948},"()",[938,979,980],{"class":948}," {\n",[938,982,984,988,991,995,998,1000,1003,1006,1009,1012,1014,1017,1019,1021,1024,1028],{"class":940,"line":983},4,[938,985,987],{"class":986},"sBMFI","    std",[938,989,990],{"class":948},"::",[938,992,994],{"class":993},"sTEyZ","shared_ptr",[938,996,997],{"class":948},"\u003C",[938,999,970],{"class":969},[938,1001,1002],{"class":948},">",[938,1004,1005],{"class":993}," p ",[938,1007,1008],{"class":948},"=",[938,1010,1011],{"class":986}," std",[938,1013,990],{"class":948},[938,1015,1016],{"class":973},"make_shared",[938,1018,997],{"class":948},[938,1020,970],{"class":969},[938,1022,1023],{"class":948},">(",[938,1025,1027],{"class":1026},"sbssI","42",[938,1029,1030],{"class":948},");\n",[938,1032,1034,1036,1038,1040,1042,1044,1046,1049,1051,1054,1057],{"class":940,"line":1033},5,[938,1035,987],{"class":986},[938,1037,990],{"class":948},[938,1039,994],{"class":993},[938,1041,997],{"class":948},[938,1043,970],{"class":969},[938,1045,1002],{"class":948},[938,1047,1048],{"class":993}," q ",[938,1050,1008],{"class":948},[938,1052,1053],{"class":993}," p",[938,1055,1056],{"class":948},";",[938,1058,1060],{"class":1059},"sHwdD"," \u002F\u002F 也可用 auto 占位符声明\n",[938,1062,1064],{"class":940,"line":1063},6,[938,1065,1066],{"class":1059},"    \u002F\u002F [...]\n",[938,1068,1070],{"class":940,"line":1069},7,[938,1071,1072],{"class":948},"}\n",[923,1074,1075,1076,1078,1079,1082,1083,1085],{},"指针 ",[919,1077,923],{}," 和 ",[919,1080,1081],{},"q"," 同时指向保存了值 ",[919,1084,1027],{}," 的资源。此外，两个指针同时持有这个资源的所有权。当所有权被多个所有者共享时，只有全部所有者都退出作用域时，资源才被释放。或者说，直到最后一个所有者退出作用域时，资源才被释放。",[929,1087,1089],{"className":931,"code":1088,"language":933,"meta":934,"style":934},"#include \u003Cmemory>\n\nint main() {\n    std::shared_ptr\u003Cint> p = std::make_shared\u003Cint>(42);\n    {\n        auto q = p; \u002F\u002F 此时 p、q 同时持有资源\n        \u002F\u002F [...]\n        \u002F\u002F q 退出作用域，但资源仍然有效；因为 p 还活跃\n    }\n    *p = 56; \u002F\u002F OK\n    \u002F\u002F p 退出作用域，它是唯一一个持有者，资源被释放\n}\n",[919,1090,1091,1101,1105,1115,1149,1154,1171,1176,1182,1188,1207,1213],{"__ignoreMap":934},[938,1092,1093,1095,1097,1099],{"class":940,"line":941},[938,1094,945],{"class":944},[938,1096,949],{"class":948},[938,1098,953],{"class":952},[938,1100,956],{"class":948},[938,1102,1103],{"class":940,"line":959},[938,1104,963],{"emptyLinePlaceholder":962},[938,1106,1107,1109,1111,1113],{"class":940,"line":966},[938,1108,970],{"class":969},[938,1110,974],{"class":973},[938,1112,977],{"class":948},[938,1114,980],{"class":948},[938,1116,1117,1119,1121,1123,1125,1127,1129,1131,1133,1135,1137,1139,1141,1143,1145,1147],{"class":940,"line":983},[938,1118,987],{"class":986},[938,1120,990],{"class":948},[938,1122,994],{"class":993},[938,1124,997],{"class":948},[938,1126,970],{"class":969},[938,1128,1002],{"class":948},[938,1130,1005],{"class":993},[938,1132,1008],{"class":948},[938,1134,1011],{"class":986},[938,1136,990],{"class":948},[938,1138,1016],{"class":973},[938,1140,997],{"class":948},[938,1142,970],{"class":969},[938,1144,1023],{"class":948},[938,1146,1027],{"class":1026},[938,1148,1030],{"class":948},[938,1150,1151],{"class":940,"line":1033},[938,1152,1153],{"class":948},"    {\n",[938,1155,1156,1159,1162,1164,1166,1168],{"class":940,"line":1063},[938,1157,1158],{"class":969},"        auto",[938,1160,1048],{"class":1161},"swJcz",[938,1163,1008],{"class":948},[938,1165,1053],{"class":1161},[938,1167,1056],{"class":948},[938,1169,1170],{"class":1059}," \u002F\u002F 此时 p、q 同时持有资源\n",[938,1172,1173],{"class":940,"line":1069},[938,1174,1175],{"class":1059},"        \u002F\u002F [...]\n",[938,1177,1179],{"class":940,"line":1178},8,[938,1180,1181],{"class":1059},"        \u002F\u002F q 退出作用域，但资源仍然有效；因为 p 还活跃\n",[938,1183,1185],{"class":940,"line":1184},9,[938,1186,1187],{"class":948},"    }\n",[938,1189,1191,1194,1197,1199,1202,1204],{"class":940,"line":1190},10,[938,1192,1193],{"class":948},"    *",[938,1195,1196],{"class":993},"p ",[938,1198,1008],{"class":948},[938,1200,1201],{"class":1026}," 56",[938,1203,1056],{"class":948},[938,1205,1206],{"class":1059}," \u002F\u002F OK\n",[938,1208,1210],{"class":940,"line":1209},11,[938,1211,1212],{"class":1059},"    \u002F\u002F p 退出作用域，它是唯一一个持有者，资源被释放\n",[938,1214,1216],{"class":940,"line":1215},12,[938,1217,1072],{"class":948},[923,1219,1220,1222,1223,1225,1226,1229,1230,1232,1233,1235],{},[919,1221,921],{}," 使用了名为引用计数的技术来实现共享所有权。每个 ",[919,1224,921],{}," 内持有两个裸指针，第一个指针指向需要管理的资源，第二个指针指向控制块。一般地，控制块内保存一个值，代表当前有多少个所有者持有该资源——即引用数（Reference count）。调用 ",[919,1227,1228],{},"std::make_shared"," 时，引用数设置为 1。当 ",[919,1231,921],{}," 被复制时，控制块内的引用数 + 1。当 ",[919,1234,921],{}," 析构时，控制块内的引用数 - 1。如果引用数减为 0，就表明没有所有者了，便释放对应资源。",[1237,1238,1239],"h2",{"id":1239},"循环引用",[923,1241,1242,1243,1245,1246,1249,1250,1252],{},"由于 ",[919,1244,921],{}," 看上去太智能了，所以容易引发一些问题。其中最常见的就是循环引用问题。考虑这样一个场景：每个人（",[919,1247,1248],{},"Person","）都拥有一个同伴，也是一个人。那么按照第七章提到的设计方式，我们应当将同伴作为 ",[919,1251,1248],{}," 类的指针成员：",[929,1254,1256],{"className":931,"code":1255,"language":933,"meta":934,"style":934},"#include \u003Cstring>\n#include \u003Cmemory>\n#include \u003Ciostream>\nclass Person {\n    std::string name;\n    std::shared_ptr\u003CPerson> partner;\npublic:\n    Person(const std::string& name) : name{name} {}\n};\n",[919,1257,1258,1269,1279,1290,1300,1312,1331,1339,1383],{"__ignoreMap":934},[938,1259,1260,1262,1264,1267],{"class":940,"line":941},[938,1261,945],{"class":944},[938,1263,949],{"class":948},[938,1265,1266],{"class":952},"string",[938,1268,956],{"class":948},[938,1270,1271,1273,1275,1277],{"class":940,"line":959},[938,1272,945],{"class":944},[938,1274,949],{"class":948},[938,1276,953],{"class":952},[938,1278,956],{"class":948},[938,1280,1281,1283,1285,1288],{"class":940,"line":966},[938,1282,945],{"class":944},[938,1284,949],{"class":948},[938,1286,1287],{"class":952},"iostream",[938,1289,956],{"class":948},[938,1291,1292,1295,1298],{"class":940,"line":983},[938,1293,1294],{"class":969},"class",[938,1296,1297],{"class":986}," Person",[938,1299,980],{"class":948},[938,1301,1302,1304,1306,1309],{"class":940,"line":1033},[938,1303,987],{"class":986},[938,1305,990],{"class":948},[938,1307,1308],{"class":1161},"string name",[938,1310,1311],{"class":948},";\n",[938,1313,1314,1316,1318,1320,1322,1324,1326,1329],{"class":940,"line":1063},[938,1315,987],{"class":986},[938,1317,990],{"class":948},[938,1319,994],{"class":1161},[938,1321,997],{"class":948},[938,1323,1248],{"class":1161},[938,1325,1002],{"class":948},[938,1327,1328],{"class":1161}," partner",[938,1330,1311],{"class":948},[938,1332,1333,1336],{"class":940,"line":1069},[938,1334,1335],{"class":969},"public",[938,1337,1338],{"class":948},":\n",[938,1340,1341,1344,1347,1350,1352,1354,1356,1359,1363,1366,1369,1371,1374,1377,1380],{"class":940,"line":1178},[938,1342,1343],{"class":973},"    Person",[938,1345,1346],{"class":948},"(",[938,1348,1349],{"class":969},"const",[938,1351,1011],{"class":986},[938,1353,990],{"class":948},[938,1355,1266],{"class":986},[938,1357,1358],{"class":969},"&",[938,1360,1362],{"class":1361},"sHdIc"," name",[938,1364,1365],{"class":948},")",[938,1367,1368],{"class":948}," :",[938,1370,1362],{"class":973},[938,1372,1373],{"class":948},"{",[938,1375,1376],{"class":1161},"name",[938,1378,1379],{"class":948},"}",[938,1381,1382],{"class":948}," {}\n",[938,1384,1385],{"class":940,"line":1184},[938,1386,1387],{"class":948},"};\n",[923,1389,1390],{},"两个人可以结为同伴：",[929,1392,1394],{"className":931,"code":1393,"language":933,"meta":934,"style":934},"#include \u003Cstring>\n#include \u003Cmemory>\n#include \u003Ciostream>\nclass Person {\n    std::string name;\n    std::shared_ptr\u003CPerson> partner;\n\npublic:\n    Person(const std::string& name) : name{name} {}\n    friend void makePartner(std::shared_ptr\u003CPerson>, std::shared_ptr\u003CPerson>);\n};\nvoid makePartner(std::shared_ptr\u003CPerson> a, std::shared_ptr\u003CPerson> b) {\n    a->partner = b;\n    b->partner = a;\n}\n",[919,1395,1396,1406,1416,1426,1434,1444,1462,1466,1472,1504,1544,1548,1594,1612,1628],{"__ignoreMap":934},[938,1397,1398,1400,1402,1404],{"class":940,"line":941},[938,1399,945],{"class":944},[938,1401,949],{"class":948},[938,1403,1266],{"class":952},[938,1405,956],{"class":948},[938,1407,1408,1410,1412,1414],{"class":940,"line":959},[938,1409,945],{"class":944},[938,1411,949],{"class":948},[938,1413,953],{"class":952},[938,1415,956],{"class":948},[938,1417,1418,1420,1422,1424],{"class":940,"line":966},[938,1419,945],{"class":944},[938,1421,949],{"class":948},[938,1423,1287],{"class":952},[938,1425,956],{"class":948},[938,1427,1428,1430,1432],{"class":940,"line":983},[938,1429,1294],{"class":969},[938,1431,1297],{"class":986},[938,1433,980],{"class":948},[938,1435,1436,1438,1440,1442],{"class":940,"line":1033},[938,1437,987],{"class":986},[938,1439,990],{"class":948},[938,1441,1308],{"class":1161},[938,1443,1311],{"class":948},[938,1445,1446,1448,1450,1452,1454,1456,1458,1460],{"class":940,"line":1063},[938,1447,987],{"class":986},[938,1449,990],{"class":948},[938,1451,994],{"class":1161},[938,1453,997],{"class":948},[938,1455,1248],{"class":1161},[938,1457,1002],{"class":948},[938,1459,1328],{"class":1161},[938,1461,1311],{"class":948},[938,1463,1464],{"class":940,"line":1069},[938,1465,963],{"emptyLinePlaceholder":962},[938,1467,1468,1470],{"class":940,"line":1178},[938,1469,1335],{"class":969},[938,1471,1338],{"class":948},[938,1473,1474,1476,1478,1480,1482,1484,1486,1488,1490,1492,1494,1496,1498,1500,1502],{"class":940,"line":1184},[938,1475,1343],{"class":973},[938,1477,1346],{"class":948},[938,1479,1349],{"class":969},[938,1481,1011],{"class":986},[938,1483,990],{"class":948},[938,1485,1266],{"class":986},[938,1487,1358],{"class":969},[938,1489,1362],{"class":1361},[938,1491,1365],{"class":948},[938,1493,1368],{"class":948},[938,1495,1362],{"class":973},[938,1497,1373],{"class":948},[938,1499,1376],{"class":1161},[938,1501,1379],{"class":948},[938,1503,1382],{"class":948},[938,1505,1506,1509,1512,1515,1517,1520,1522,1524,1526,1528,1531,1533,1535,1537,1539,1541],{"class":940,"line":1190},[938,1507,1508],{"class":969},"    friend",[938,1510,1511],{"class":969}," void",[938,1513,1514],{"class":973}," makePartner",[938,1516,1346],{"class":948},[938,1518,1519],{"class":986},"std",[938,1521,990],{"class":948},[938,1523,994],{"class":986},[938,1525,997],{"class":948},[938,1527,1248],{"class":986},[938,1529,1530],{"class":948},">,",[938,1532,1011],{"class":986},[938,1534,990],{"class":948},[938,1536,994],{"class":986},[938,1538,997],{"class":948},[938,1540,1248],{"class":986},[938,1542,1543],{"class":948},">);\n",[938,1545,1546],{"class":940,"line":1209},[938,1547,1387],{"class":948},[938,1549,1550,1553,1555,1557,1559,1561,1563,1565,1567,1569,1572,1575,1577,1579,1581,1583,1585,1587,1590,1592],{"class":940,"line":1215},[938,1551,1552],{"class":969},"void",[938,1554,1514],{"class":973},[938,1556,1346],{"class":948},[938,1558,1519],{"class":986},[938,1560,990],{"class":948},[938,1562,994],{"class":986},[938,1564,997],{"class":948},[938,1566,1248],{"class":986},[938,1568,1002],{"class":948},[938,1570,1571],{"class":1361}," a",[938,1573,1574],{"class":948},",",[938,1576,1011],{"class":986},[938,1578,990],{"class":948},[938,1580,994],{"class":986},[938,1582,997],{"class":948},[938,1584,1248],{"class":986},[938,1586,1002],{"class":948},[938,1588,1589],{"class":1361}," b",[938,1591,1365],{"class":948},[938,1593,980],{"class":948},[938,1595,1597,1600,1603,1606,1608,1610],{"class":940,"line":1596},13,[938,1598,1599],{"class":993},"    a",[938,1601,1602],{"class":948},"->",[938,1604,1605],{"class":993},"partner ",[938,1607,1008],{"class":948},[938,1609,1589],{"class":993},[938,1611,1311],{"class":948},[938,1613,1615,1618,1620,1622,1624,1626],{"class":940,"line":1614},14,[938,1616,1617],{"class":993},"    b",[938,1619,1602],{"class":948},[938,1621,1605],{"class":993},[938,1623,1008],{"class":948},[938,1625,1571],{"class":993},[938,1627,1311],{"class":948},[938,1629,1631],{"class":940,"line":1630},15,[938,1632,1072],{"class":948},[923,1634,1635],{},"然后试一试：",[929,1637,1639],{"className":931,"code":1638,"language":933,"meta":934,"style":934},"#include \u003Cstring>\n#include \u003Cmemory>\n#include \u003Ciostream>\nclass Person {\n    std::string name;\n    std::shared_ptr\u003CPerson> partner;\n\npublic:\n    Person(const std::string& name) : name{name} {}\n    friend void makePartner(std::shared_ptr\u003CPerson>, std::shared_ptr\u003CPerson>);\n};\nvoid makePartner(std::shared_ptr\u003CPerson> a, std::shared_ptr\u003CPerson> b) {\n    a->partner = b;\n    b->partner = a;\n}\nint main() {\n    auto alice = std::make_shared\u003CPerson>(\"Alice\");\n    auto bob = std::make_shared\u003CPerson>(\"Bob\");\n    makePartner(alice, bob);\n    \u002F\u002F 看上去挺不错？\n}\n",[919,1640,1641,1651,1661,1671,1679,1689,1707,1711,1717,1749,1783,1787,1829,1843,1857,1861,1872,1905,1936,1954,1960],{"__ignoreMap":934},[938,1642,1643,1645,1647,1649],{"class":940,"line":941},[938,1644,945],{"class":944},[938,1646,949],{"class":948},[938,1648,1266],{"class":952},[938,1650,956],{"class":948},[938,1652,1653,1655,1657,1659],{"class":940,"line":959},[938,1654,945],{"class":944},[938,1656,949],{"class":948},[938,1658,953],{"class":952},[938,1660,956],{"class":948},[938,1662,1663,1665,1667,1669],{"class":940,"line":966},[938,1664,945],{"class":944},[938,1666,949],{"class":948},[938,1668,1287],{"class":952},[938,1670,956],{"class":948},[938,1672,1673,1675,1677],{"class":940,"line":983},[938,1674,1294],{"class":969},[938,1676,1297],{"class":986},[938,1678,980],{"class":948},[938,1680,1681,1683,1685,1687],{"class":940,"line":1033},[938,1682,987],{"class":986},[938,1684,990],{"class":948},[938,1686,1308],{"class":1161},[938,1688,1311],{"class":948},[938,1690,1691,1693,1695,1697,1699,1701,1703,1705],{"class":940,"line":1063},[938,1692,987],{"class":986},[938,1694,990],{"class":948},[938,1696,994],{"class":1161},[938,1698,997],{"class":948},[938,1700,1248],{"class":1161},[938,1702,1002],{"class":948},[938,1704,1328],{"class":1161},[938,1706,1311],{"class":948},[938,1708,1709],{"class":940,"line":1069},[938,1710,963],{"emptyLinePlaceholder":962},[938,1712,1713,1715],{"class":940,"line":1178},[938,1714,1335],{"class":969},[938,1716,1338],{"class":948},[938,1718,1719,1721,1723,1725,1727,1729,1731,1733,1735,1737,1739,1741,1743,1745,1747],{"class":940,"line":1184},[938,1720,1343],{"class":973},[938,1722,1346],{"class":948},[938,1724,1349],{"class":969},[938,1726,1011],{"class":986},[938,1728,990],{"class":948},[938,1730,1266],{"class":986},[938,1732,1358],{"class":969},[938,1734,1362],{"class":1361},[938,1736,1365],{"class":948},[938,1738,1368],{"class":948},[938,1740,1362],{"class":973},[938,1742,1373],{"class":948},[938,1744,1376],{"class":1161},[938,1746,1379],{"class":948},[938,1748,1382],{"class":948},[938,1750,1751,1753,1755,1757,1759,1761,1763,1765,1767,1769,1771,1773,1775,1777,1779,1781],{"class":940,"line":1190},[938,1752,1508],{"class":969},[938,1754,1511],{"class":969},[938,1756,1514],{"class":973},[938,1758,1346],{"class":948},[938,1760,1519],{"class":986},[938,1762,990],{"class":948},[938,1764,994],{"class":986},[938,1766,997],{"class":948},[938,1768,1248],{"class":986},[938,1770,1530],{"class":948},[938,1772,1011],{"class":986},[938,1774,990],{"class":948},[938,1776,994],{"class":986},[938,1778,997],{"class":948},[938,1780,1248],{"class":986},[938,1782,1543],{"class":948},[938,1784,1785],{"class":940,"line":1209},[938,1786,1387],{"class":948},[938,1788,1789,1791,1793,1795,1797,1799,1801,1803,1805,1807,1809,1811,1813,1815,1817,1819,1821,1823,1825,1827],{"class":940,"line":1215},[938,1790,1552],{"class":969},[938,1792,1514],{"class":973},[938,1794,1346],{"class":948},[938,1796,1519],{"class":986},[938,1798,990],{"class":948},[938,1800,994],{"class":986},[938,1802,997],{"class":948},[938,1804,1248],{"class":986},[938,1806,1002],{"class":948},[938,1808,1571],{"class":1361},[938,1810,1574],{"class":948},[938,1812,1011],{"class":986},[938,1814,990],{"class":948},[938,1816,994],{"class":986},[938,1818,997],{"class":948},[938,1820,1248],{"class":986},[938,1822,1002],{"class":948},[938,1824,1589],{"class":1361},[938,1826,1365],{"class":948},[938,1828,980],{"class":948},[938,1830,1831,1833,1835,1837,1839,1841],{"class":940,"line":1596},[938,1832,1599],{"class":993},[938,1834,1602],{"class":948},[938,1836,1605],{"class":993},[938,1838,1008],{"class":948},[938,1840,1589],{"class":993},[938,1842,1311],{"class":948},[938,1844,1845,1847,1849,1851,1853,1855],{"class":940,"line":1614},[938,1846,1617],{"class":993},[938,1848,1602],{"class":948},[938,1850,1605],{"class":993},[938,1852,1008],{"class":948},[938,1854,1571],{"class":993},[938,1856,1311],{"class":948},[938,1858,1859],{"class":940,"line":1630},[938,1860,1072],{"class":948},[938,1862,1864,1866,1868,1870],{"class":940,"line":1863},16,[938,1865,970],{"class":969},[938,1867,974],{"class":973},[938,1869,977],{"class":948},[938,1871,980],{"class":948},[938,1873,1875,1878,1881,1883,1885,1887,1889,1891,1893,1895,1898,1901,1903],{"class":940,"line":1874},17,[938,1876,1877],{"class":969},"    auto",[938,1879,1880],{"class":993}," alice ",[938,1882,1008],{"class":948},[938,1884,1011],{"class":986},[938,1886,990],{"class":948},[938,1888,1016],{"class":973},[938,1890,997],{"class":948},[938,1892,1248],{"class":986},[938,1894,1023],{"class":948},[938,1896,1897],{"class":948},"\"",[938,1899,1900],{"class":952},"Alice",[938,1902,1897],{"class":948},[938,1904,1030],{"class":948},[938,1906,1908,1910,1913,1915,1917,1919,1921,1923,1925,1927,1929,1932,1934],{"class":940,"line":1907},18,[938,1909,1877],{"class":969},[938,1911,1912],{"class":993}," bob ",[938,1914,1008],{"class":948},[938,1916,1011],{"class":986},[938,1918,990],{"class":948},[938,1920,1016],{"class":973},[938,1922,997],{"class":948},[938,1924,1248],{"class":986},[938,1926,1023],{"class":948},[938,1928,1897],{"class":948},[938,1930,1931],{"class":952},"Bob",[938,1933,1897],{"class":948},[938,1935,1030],{"class":948},[938,1937,1939,1942,1944,1947,1949,1952],{"class":940,"line":1938},19,[938,1940,1941],{"class":973},"    makePartner",[938,1943,1346],{"class":948},[938,1945,1946],{"class":993},"alice",[938,1948,1574],{"class":948},[938,1950,1951],{"class":993}," bob",[938,1953,1030],{"class":948},[938,1955,1957],{"class":940,"line":1956},20,[938,1958,1959],{"class":1059},"    \u002F\u002F 看上去挺不错？\n",[938,1961,1963],{"class":940,"line":1962},21,[938,1964,1072],{"class":948},[923,1966,1967],{},"但如果我们在构造函数和析构函数加上输出来观察的话，就会发现……",[929,1969,1971],{"className":931,"code":1970,"language":933,"meta":934,"style":934},"#include \u003Cstring>\n#include \u003Cmemory>\n#include \u003Ciostream>\nclass Person {\n    std::string name;\n    std::shared_ptr\u003CPerson> partner;\n\npublic:\n    Person(const std::string& name) : name{name} {\n        std::cout \u003C\u003C \"Constructor for \" \u003C\u003C name \u003C\u003C \" called\" \u003C\u003C std::endl;\n    }\n    ~Person() {\n        std::cout \u003C\u003C \"Destructor for \" \u003C\u003C name \u003C\u003C \" called\" \u003C\u003C std::endl;\n    }\n    friend void makePartner(std::shared_ptr\u003CPerson>, std::shared_ptr\u003CPerson>);\n};\nvoid makePartner(std::shared_ptr\u003CPerson> a, std::shared_ptr\u003CPerson> b) {\n    a->partner = b;\n    b->partner = a;\n}\nint main() {\n    auto alice = std::make_shared\u003CPerson>(\"Alice\");\n    auto bob = std::make_shared\u003CPerson>(\"Bob\");\n    makePartner(alice, bob);\n    \u002F\u002F 看上去挺不错？\n}\n",[919,1972,1973,1983,1993,2003,2011,2021,2039,2043,2049,2081,2128,2132,2141,2180,2184,2218,2222,2264,2278,2292,2296,2306,2335,2364,2379,2384],{"__ignoreMap":934},[938,1974,1975,1977,1979,1981],{"class":940,"line":941},[938,1976,945],{"class":944},[938,1978,949],{"class":948},[938,1980,1266],{"class":952},[938,1982,956],{"class":948},[938,1984,1985,1987,1989,1991],{"class":940,"line":959},[938,1986,945],{"class":944},[938,1988,949],{"class":948},[938,1990,953],{"class":952},[938,1992,956],{"class":948},[938,1994,1995,1997,1999,2001],{"class":940,"line":966},[938,1996,945],{"class":944},[938,1998,949],{"class":948},[938,2000,1287],{"class":952},[938,2002,956],{"class":948},[938,2004,2005,2007,2009],{"class":940,"line":983},[938,2006,1294],{"class":969},[938,2008,1297],{"class":986},[938,2010,980],{"class":948},[938,2012,2013,2015,2017,2019],{"class":940,"line":1033},[938,2014,987],{"class":986},[938,2016,990],{"class":948},[938,2018,1308],{"class":1161},[938,2020,1311],{"class":948},[938,2022,2023,2025,2027,2029,2031,2033,2035,2037],{"class":940,"line":1063},[938,2024,987],{"class":986},[938,2026,990],{"class":948},[938,2028,994],{"class":1161},[938,2030,997],{"class":948},[938,2032,1248],{"class":1161},[938,2034,1002],{"class":948},[938,2036,1328],{"class":1161},[938,2038,1311],{"class":948},[938,2040,2041],{"class":940,"line":1069},[938,2042,963],{"emptyLinePlaceholder":962},[938,2044,2045,2047],{"class":940,"line":1178},[938,2046,1335],{"class":969},[938,2048,1338],{"class":948},[938,2050,2051,2053,2055,2057,2059,2061,2063,2065,2067,2069,2071,2073,2075,2077,2079],{"class":940,"line":1184},[938,2052,1343],{"class":973},[938,2054,1346],{"class":948},[938,2056,1349],{"class":969},[938,2058,1011],{"class":986},[938,2060,990],{"class":948},[938,2062,1266],{"class":986},[938,2064,1358],{"class":969},[938,2066,1362],{"class":1361},[938,2068,1365],{"class":948},[938,2070,1368],{"class":948},[938,2072,1362],{"class":973},[938,2074,1373],{"class":948},[938,2076,1376],{"class":1161},[938,2078,1379],{"class":948},[938,2080,980],{"class":948},[938,2082,2083,2086,2088,2091,2094,2097,2100,2102,2105,2108,2110,2112,2115,2117,2119,2121,2123,2126],{"class":940,"line":1190},[938,2084,2085],{"class":986},"        std",[938,2087,990],{"class":948},[938,2089,2090],{"class":1161},"cout ",[938,2092,2093],{"class":948},"\u003C\u003C",[938,2095,2096],{"class":948}," \"",[938,2098,2099],{"class":952},"Constructor for ",[938,2101,1897],{"class":948},[938,2103,2104],{"class":948}," \u003C\u003C",[938,2106,2107],{"class":1161}," name ",[938,2109,2093],{"class":948},[938,2111,2096],{"class":948},[938,2113,2114],{"class":952}," called",[938,2116,1897],{"class":948},[938,2118,2104],{"class":948},[938,2120,1011],{"class":986},[938,2122,990],{"class":948},[938,2124,2125],{"class":1161},"endl",[938,2127,1311],{"class":948},[938,2129,2130],{"class":940,"line":1209},[938,2131,1187],{"class":948},[938,2133,2134,2137,2139],{"class":940,"line":1215},[938,2135,2136],{"class":973},"    ~Person",[938,2138,977],{"class":948},[938,2140,980],{"class":948},[938,2142,2143,2145,2147,2149,2151,2153,2156,2158,2160,2162,2164,2166,2168,2170,2172,2174,2176,2178],{"class":940,"line":1596},[938,2144,2085],{"class":986},[938,2146,990],{"class":948},[938,2148,2090],{"class":1161},[938,2150,2093],{"class":948},[938,2152,2096],{"class":948},[938,2154,2155],{"class":952},"Destructor for ",[938,2157,1897],{"class":948},[938,2159,2104],{"class":948},[938,2161,2107],{"class":1161},[938,2163,2093],{"class":948},[938,2165,2096],{"class":948},[938,2167,2114],{"class":952},[938,2169,1897],{"class":948},[938,2171,2104],{"class":948},[938,2173,1011],{"class":986},[938,2175,990],{"class":948},[938,2177,2125],{"class":1161},[938,2179,1311],{"class":948},[938,2181,2182],{"class":940,"line":1614},[938,2183,1187],{"class":948},[938,2185,2186,2188,2190,2192,2194,2196,2198,2200,2202,2204,2206,2208,2210,2212,2214,2216],{"class":940,"line":1630},[938,2187,1508],{"class":969},[938,2189,1511],{"class":969},[938,2191,1514],{"class":973},[938,2193,1346],{"class":948},[938,2195,1519],{"class":986},[938,2197,990],{"class":948},[938,2199,994],{"class":986},[938,2201,997],{"class":948},[938,2203,1248],{"class":986},[938,2205,1530],{"class":948},[938,2207,1011],{"class":986},[938,2209,990],{"class":948},[938,2211,994],{"class":986},[938,2213,997],{"class":948},[938,2215,1248],{"class":986},[938,2217,1543],{"class":948},[938,2219,2220],{"class":940,"line":1863},[938,2221,1387],{"class":948},[938,2223,2224,2226,2228,2230,2232,2234,2236,2238,2240,2242,2244,2246,2248,2250,2252,2254,2256,2258,2260,2262],{"class":940,"line":1874},[938,2225,1552],{"class":969},[938,2227,1514],{"class":973},[938,2229,1346],{"class":948},[938,2231,1519],{"class":986},[938,2233,990],{"class":948},[938,2235,994],{"class":986},[938,2237,997],{"class":948},[938,2239,1248],{"class":986},[938,2241,1002],{"class":948},[938,2243,1571],{"class":1361},[938,2245,1574],{"class":948},[938,2247,1011],{"class":986},[938,2249,990],{"class":948},[938,2251,994],{"class":986},[938,2253,997],{"class":948},[938,2255,1248],{"class":986},[938,2257,1002],{"class":948},[938,2259,1589],{"class":1361},[938,2261,1365],{"class":948},[938,2263,980],{"class":948},[938,2265,2266,2268,2270,2272,2274,2276],{"class":940,"line":1907},[938,2267,1599],{"class":993},[938,2269,1602],{"class":948},[938,2271,1605],{"class":993},[938,2273,1008],{"class":948},[938,2275,1589],{"class":993},[938,2277,1311],{"class":948},[938,2279,2280,2282,2284,2286,2288,2290],{"class":940,"line":1938},[938,2281,1617],{"class":993},[938,2283,1602],{"class":948},[938,2285,1605],{"class":993},[938,2287,1008],{"class":948},[938,2289,1571],{"class":993},[938,2291,1311],{"class":948},[938,2293,2294],{"class":940,"line":1956},[938,2295,1072],{"class":948},[938,2297,2298,2300,2302,2304],{"class":940,"line":1962},[938,2299,970],{"class":969},[938,2301,974],{"class":973},[938,2303,977],{"class":948},[938,2305,980],{"class":948},[938,2307,2309,2311,2313,2315,2317,2319,2321,2323,2325,2327,2329,2331,2333],{"class":940,"line":2308},22,[938,2310,1877],{"class":969},[938,2312,1880],{"class":993},[938,2314,1008],{"class":948},[938,2316,1011],{"class":986},[938,2318,990],{"class":948},[938,2320,1016],{"class":973},[938,2322,997],{"class":948},[938,2324,1248],{"class":986},[938,2326,1023],{"class":948},[938,2328,1897],{"class":948},[938,2330,1900],{"class":952},[938,2332,1897],{"class":948},[938,2334,1030],{"class":948},[938,2336,2338,2340,2342,2344,2346,2348,2350,2352,2354,2356,2358,2360,2362],{"class":940,"line":2337},23,[938,2339,1877],{"class":969},[938,2341,1912],{"class":993},[938,2343,1008],{"class":948},[938,2345,1011],{"class":986},[938,2347,990],{"class":948},[938,2349,1016],{"class":973},[938,2351,997],{"class":948},[938,2353,1248],{"class":986},[938,2355,1023],{"class":948},[938,2357,1897],{"class":948},[938,2359,1931],{"class":952},[938,2361,1897],{"class":948},[938,2363,1030],{"class":948},[938,2365,2367,2369,2371,2373,2375,2377],{"class":940,"line":2366},24,[938,2368,1941],{"class":973},[938,2370,1346],{"class":948},[938,2372,1946],{"class":993},[938,2374,1574],{"class":948},[938,2376,1951],{"class":993},[938,2378,1030],{"class":948},[938,2380,2382],{"class":940,"line":2381},25,[938,2383,1959],{"class":1059},[938,2385,2387],{"class":940,"line":2386},26,[938,2388,1072],{"class":948},[923,2390,2391,2392,2394,2395,2397,2398,2401],{},"刚刚的代码根本没有调用析构函数！而这个问题的原因就是循环引用。首先，",[919,2393,921],{}," 释放资源的前提是，最后一次 ",[919,2396,921],{}," 本身析构后，引用计数降为 0。但仔细观察这份代码：当 Alice 想要析构的时候，Bob 的 ",[919,2399,2400],{},"partner"," 成员却持有所有权，导致 Alice 的引用计数仍然不为 0。Bob 方面同理，由于 Alice 也持有着 Bob 的所有权，所以 Bob 也不能析构。这样，两者互相牵制对方，析构函数总是无法调用。",[923,2403,2404,2405,2407,2408,2410,2411,2413],{},"那么解决方法呢？最简单的：直接将 ",[919,2406,2400],{}," 成员设置为裸指针。裸指针不具有所有权，不会影响 ",[919,2409,921],{}," 的控制块引用计数。但问题是裸指针是潜在危险的：如果这个指针指向的资源已经被 ",[919,2412,921],{}," 自动释放了，那么裸指针就变成了危险的野指针。",[923,2415,2416,2417,2420,2421,2423,2424,2428,2429,2431,2432,2434,2435,2437],{},"为此，标准库提供了 ",[919,2418,2419],{},"std::weak_ptr"," 来解决循环引用问题。简单来说，",[919,2422,2419],{}," 是",[2425,2426,2427],"strong",{},"不含所有权","的 ",[919,2430,921],{},"。换而言之，将 ",[919,2433,921],{}," 复制给一个 ",[919,2436,2419],{}," 不会增加引用计数。",[923,2439,2440,2441,2443,2444,2446,2447,2449,2450,2452,2453,2455],{},"但 ",[919,2442,2419],{}," 不同于 ",[919,2445,921],{}," 的重要之处在于，",[919,2448,2419],{}," 也会保存指向控制块的指针。也就是说，一个 ",[919,2451,2419],{}," 可以知道目前其所指向的资源的引用计数。这时，如果引用计数为 0，就意味着资源已经释放。当 ",[919,2454,2419],{}," 发现资源已经释放时，就不可以再访问这个资源。",[923,2457,2458,2459,2461,2462,2465,2466,2469,2470,2473,2474,2477,2478,2480,2481,2484,2485,2487,2488,2490],{},"上述限制资源访问的方法是：",[919,2460,2419],{}," 不定义一元 ",[919,2463,2464],{},"operator*","、",[919,2467,2468],{},"operator->"," 或 ",[919,2471,2472],{},"operator[]","，以及任何可以直接访问到指针本身的操作（如 ",[919,2475,2476],{},"get"," 成员函数）。如果要访问 ",[919,2479,2419],{}," 所指向的资源，则必须通过 ",[919,2482,2483],{},"lock"," 成员函数——该成员函数检查资源可用性后，返回指向资源的 ",[919,2486,921],{},"；否则返回空指针。你只需要保证调用 ",[919,2489,2483],{}," 成员函数时处于一个“局部”作用域内，就能保证不会出现循环引用。",[923,2492,2493,2494,2496],{},"使用 ",[919,2495,2419],{}," 改写后的代码如下：",[929,2498,2500],{"className":931,"code":2499,"language":933,"meta":934,"style":934},"#include \u003Cstring>\n#include \u003Cmemory>\n#include \u003Ciostream>\nclass Person {\n    std::string name;\n    std::weak_ptr\u003CPerson> partner; \u002F\u002F 不持有同伴的所有权\n\npublic:\n    Person(const std::string& name) : name{name} {\n        std::cout \u003C\u003C \"Constructor for \" \u003C\u003C name \u003C\u003C \" called\" \u003C\u003C std::endl;\n    }\n    ~Person() {\n        std::cout \u003C\u003C \"Destructor for \" \u003C\u003C name \u003C\u003C \" called\" \u003C\u003C std::endl;\n    }\n    friend void makePartner(std::shared_ptr\u003CPerson>, std::shared_ptr\u003CPerson>);\n\n    \u002F\u002F 演示 std::weak_ptr 用法：需要时 lock\n    void getPartnerName() const {\n        if (auto p{partner.lock()}) {\n            std::cout \u003C\u003C \"My partner is \" \u003C\u003C p->name \u003C\u003C std::endl;\n        } else {\n            std::cout \u003C\u003C \"No partner, or partner is destructed\" \u003C\u003C std::endl;\n        }\n    }\n};\nvoid makePartner(std::shared_ptr\u003CPerson> a, std::shared_ptr\u003CPerson> b) {\n    a->partner = b;\n    b->partner = a;\n}\nint main() {\n    auto alice = std::make_shared\u003CPerson>(\"Alice\");\n    {\n        auto bob = std::make_shared\u003CPerson>(\"Bob\");\n        makePartner(alice, bob);\n        alice->getPartnerName();\n    }\n    alice->getPartnerName();\n}\n",[919,2501,2502,2512,2522,2532,2540,2550,2572,2576,2582,2614,2652,2656,2664,2702,2706,2740,2744,2749,2764,2793,2829,2839,2866,2871,2875,2879,2921,2936,2951,2956,2967,2996,3001,3030,3046,3060,3065,3077],{"__ignoreMap":934},[938,2503,2504,2506,2508,2510],{"class":940,"line":941},[938,2505,945],{"class":944},[938,2507,949],{"class":948},[938,2509,1266],{"class":952},[938,2511,956],{"class":948},[938,2513,2514,2516,2518,2520],{"class":940,"line":959},[938,2515,945],{"class":944},[938,2517,949],{"class":948},[938,2519,953],{"class":952},[938,2521,956],{"class":948},[938,2523,2524,2526,2528,2530],{"class":940,"line":966},[938,2525,945],{"class":944},[938,2527,949],{"class":948},[938,2529,1287],{"class":952},[938,2531,956],{"class":948},[938,2533,2534,2536,2538],{"class":940,"line":983},[938,2535,1294],{"class":969},[938,2537,1297],{"class":986},[938,2539,980],{"class":948},[938,2541,2542,2544,2546,2548],{"class":940,"line":1033},[938,2543,987],{"class":986},[938,2545,990],{"class":948},[938,2547,1308],{"class":1161},[938,2549,1311],{"class":948},[938,2551,2552,2554,2556,2559,2561,2563,2565,2567,2569],{"class":940,"line":1063},[938,2553,987],{"class":986},[938,2555,990],{"class":948},[938,2557,2558],{"class":1161},"weak_ptr",[938,2560,997],{"class":948},[938,2562,1248],{"class":1161},[938,2564,1002],{"class":948},[938,2566,1328],{"class":1161},[938,2568,1056],{"class":948},[938,2570,2571],{"class":1059}," \u002F\u002F 不持有同伴的所有权\n",[938,2573,2574],{"class":940,"line":1069},[938,2575,963],{"emptyLinePlaceholder":962},[938,2577,2578,2580],{"class":940,"line":1178},[938,2579,1335],{"class":969},[938,2581,1338],{"class":948},[938,2583,2584,2586,2588,2590,2592,2594,2596,2598,2600,2602,2604,2606,2608,2610,2612],{"class":940,"line":1184},[938,2585,1343],{"class":973},[938,2587,1346],{"class":948},[938,2589,1349],{"class":969},[938,2591,1011],{"class":986},[938,2593,990],{"class":948},[938,2595,1266],{"class":986},[938,2597,1358],{"class":969},[938,2599,1362],{"class":1361},[938,2601,1365],{"class":948},[938,2603,1368],{"class":948},[938,2605,1362],{"class":973},[938,2607,1373],{"class":948},[938,2609,1376],{"class":1161},[938,2611,1379],{"class":948},[938,2613,980],{"class":948},[938,2615,2616,2618,2620,2622,2624,2626,2628,2630,2632,2634,2636,2638,2640,2642,2644,2646,2648,2650],{"class":940,"line":1190},[938,2617,2085],{"class":986},[938,2619,990],{"class":948},[938,2621,2090],{"class":1161},[938,2623,2093],{"class":948},[938,2625,2096],{"class":948},[938,2627,2099],{"class":952},[938,2629,1897],{"class":948},[938,2631,2104],{"class":948},[938,2633,2107],{"class":1161},[938,2635,2093],{"class":948},[938,2637,2096],{"class":948},[938,2639,2114],{"class":952},[938,2641,1897],{"class":948},[938,2643,2104],{"class":948},[938,2645,1011],{"class":986},[938,2647,990],{"class":948},[938,2649,2125],{"class":1161},[938,2651,1311],{"class":948},[938,2653,2654],{"class":940,"line":1209},[938,2655,1187],{"class":948},[938,2657,2658,2660,2662],{"class":940,"line":1215},[938,2659,2136],{"class":973},[938,2661,977],{"class":948},[938,2663,980],{"class":948},[938,2665,2666,2668,2670,2672,2674,2676,2678,2680,2682,2684,2686,2688,2690,2692,2694,2696,2698,2700],{"class":940,"line":1596},[938,2667,2085],{"class":986},[938,2669,990],{"class":948},[938,2671,2090],{"class":1161},[938,2673,2093],{"class":948},[938,2675,2096],{"class":948},[938,2677,2155],{"class":952},[938,2679,1897],{"class":948},[938,2681,2104],{"class":948},[938,2683,2107],{"class":1161},[938,2685,2093],{"class":948},[938,2687,2096],{"class":948},[938,2689,2114],{"class":952},[938,2691,1897],{"class":948},[938,2693,2104],{"class":948},[938,2695,1011],{"class":986},[938,2697,990],{"class":948},[938,2699,2125],{"class":1161},[938,2701,1311],{"class":948},[938,2703,2704],{"class":940,"line":1614},[938,2705,1187],{"class":948},[938,2707,2708,2710,2712,2714,2716,2718,2720,2722,2724,2726,2728,2730,2732,2734,2736,2738],{"class":940,"line":1630},[938,2709,1508],{"class":969},[938,2711,1511],{"class":969},[938,2713,1514],{"class":973},[938,2715,1346],{"class":948},[938,2717,1519],{"class":986},[938,2719,990],{"class":948},[938,2721,994],{"class":986},[938,2723,997],{"class":948},[938,2725,1248],{"class":986},[938,2727,1530],{"class":948},[938,2729,1011],{"class":986},[938,2731,990],{"class":948},[938,2733,994],{"class":986},[938,2735,997],{"class":948},[938,2737,1248],{"class":986},[938,2739,1543],{"class":948},[938,2741,2742],{"class":940,"line":1863},[938,2743,963],{"emptyLinePlaceholder":962},[938,2745,2746],{"class":940,"line":1874},[938,2747,2748],{"class":1059},"    \u002F\u002F 演示 std::weak_ptr 用法：需要时 lock\n",[938,2750,2751,2754,2757,2759,2762],{"class":940,"line":1907},[938,2752,2753],{"class":969},"    void",[938,2755,2756],{"class":973}," getPartnerName",[938,2758,977],{"class":948},[938,2760,2761],{"class":969}," const",[938,2763,980],{"class":948},[938,2765,2766,2769,2772,2775,2778,2780,2783,2785,2787,2789,2791],{"class":940,"line":1938},[938,2767,2768],{"class":944},"        if",[938,2770,2771],{"class":948}," (",[938,2773,2774],{"class":969},"auto",[938,2776,2777],{"class":1161}," p{",[938,2779,2400],{"class":993},[938,2781,2782],{"class":948},".",[938,2784,2483],{"class":973},[938,2786,977],{"class":948},[938,2788,1379],{"class":1161},[938,2790,1365],{"class":948},[938,2792,980],{"class":948},[938,2794,2795,2798,2800,2802,2804,2806,2809,2811,2813,2815,2817,2819,2821,2823,2825,2827],{"class":940,"line":1956},[938,2796,2797],{"class":986},"            std",[938,2799,990],{"class":948},[938,2801,2090],{"class":1161},[938,2803,2093],{"class":948},[938,2805,2096],{"class":948},[938,2807,2808],{"class":952},"My partner is ",[938,2810,1897],{"class":948},[938,2812,2104],{"class":948},[938,2814,1053],{"class":993},[938,2816,1602],{"class":948},[938,2818,1376],{"class":993},[938,2820,2104],{"class":948},[938,2822,1011],{"class":986},[938,2824,990],{"class":948},[938,2826,2125],{"class":1161},[938,2828,1311],{"class":948},[938,2830,2831,2834,2837],{"class":940,"line":1962},[938,2832,2833],{"class":948},"        }",[938,2835,2836],{"class":944}," else",[938,2838,980],{"class":948},[938,2840,2841,2843,2845,2847,2849,2851,2854,2856,2858,2860,2862,2864],{"class":940,"line":2308},[938,2842,2797],{"class":986},[938,2844,990],{"class":948},[938,2846,2090],{"class":1161},[938,2848,2093],{"class":948},[938,2850,2096],{"class":948},[938,2852,2853],{"class":952},"No partner, or partner is destructed",[938,2855,1897],{"class":948},[938,2857,2104],{"class":948},[938,2859,1011],{"class":986},[938,2861,990],{"class":948},[938,2863,2125],{"class":1161},[938,2865,1311],{"class":948},[938,2867,2868],{"class":940,"line":2337},[938,2869,2870],{"class":948},"        }\n",[938,2872,2873],{"class":940,"line":2366},[938,2874,1187],{"class":948},[938,2876,2877],{"class":940,"line":2381},[938,2878,1387],{"class":948},[938,2880,2881,2883,2885,2887,2889,2891,2893,2895,2897,2899,2901,2903,2905,2907,2909,2911,2913,2915,2917,2919],{"class":940,"line":2386},[938,2882,1552],{"class":969},[938,2884,1514],{"class":973},[938,2886,1346],{"class":948},[938,2888,1519],{"class":986},[938,2890,990],{"class":948},[938,2892,994],{"class":986},[938,2894,997],{"class":948},[938,2896,1248],{"class":986},[938,2898,1002],{"class":948},[938,2900,1571],{"class":1361},[938,2902,1574],{"class":948},[938,2904,1011],{"class":986},[938,2906,990],{"class":948},[938,2908,994],{"class":986},[938,2910,997],{"class":948},[938,2912,1248],{"class":986},[938,2914,1002],{"class":948},[938,2916,1589],{"class":1361},[938,2918,1365],{"class":948},[938,2920,980],{"class":948},[938,2922,2924,2926,2928,2930,2932,2934],{"class":940,"line":2923},27,[938,2925,1599],{"class":993},[938,2927,1602],{"class":948},[938,2929,1605],{"class":993},[938,2931,1008],{"class":948},[938,2933,1589],{"class":993},[938,2935,1311],{"class":948},[938,2937,2939,2941,2943,2945,2947,2949],{"class":940,"line":2938},28,[938,2940,1617],{"class":993},[938,2942,1602],{"class":948},[938,2944,1605],{"class":993},[938,2946,1008],{"class":948},[938,2948,1571],{"class":993},[938,2950,1311],{"class":948},[938,2952,2954],{"class":940,"line":2953},29,[938,2955,1072],{"class":948},[938,2957,2959,2961,2963,2965],{"class":940,"line":2958},30,[938,2960,970],{"class":969},[938,2962,974],{"class":973},[938,2964,977],{"class":948},[938,2966,980],{"class":948},[938,2968,2970,2972,2974,2976,2978,2980,2982,2984,2986,2988,2990,2992,2994],{"class":940,"line":2969},31,[938,2971,1877],{"class":969},[938,2973,1880],{"class":993},[938,2975,1008],{"class":948},[938,2977,1011],{"class":986},[938,2979,990],{"class":948},[938,2981,1016],{"class":973},[938,2983,997],{"class":948},[938,2985,1248],{"class":986},[938,2987,1023],{"class":948},[938,2989,1897],{"class":948},[938,2991,1900],{"class":952},[938,2993,1897],{"class":948},[938,2995,1030],{"class":948},[938,2997,2999],{"class":940,"line":2998},32,[938,3000,1153],{"class":948},[938,3002,3004,3006,3008,3010,3012,3014,3016,3018,3020,3022,3024,3026,3028],{"class":940,"line":3003},33,[938,3005,1158],{"class":969},[938,3007,1912],{"class":1161},[938,3009,1008],{"class":948},[938,3011,1011],{"class":986},[938,3013,990],{"class":948},[938,3015,1016],{"class":973},[938,3017,997],{"class":948},[938,3019,1248],{"class":986},[938,3021,1023],{"class":948},[938,3023,1897],{"class":948},[938,3025,1931],{"class":952},[938,3027,1897],{"class":948},[938,3029,1030],{"class":948},[938,3031,3033,3036,3038,3040,3042,3044],{"class":940,"line":3032},34,[938,3034,3035],{"class":973},"        makePartner",[938,3037,1346],{"class":948},[938,3039,1946],{"class":1161},[938,3041,1574],{"class":948},[938,3043,1951],{"class":1161},[938,3045,1030],{"class":948},[938,3047,3049,3052,3054,3057],{"class":940,"line":3048},35,[938,3050,3051],{"class":993},"        alice",[938,3053,1602],{"class":948},[938,3055,3056],{"class":973},"getPartnerName",[938,3058,3059],{"class":948},"();\n",[938,3061,3063],{"class":940,"line":3062},36,[938,3064,1187],{"class":948},[938,3066,3068,3071,3073,3075],{"class":940,"line":3067},37,[938,3069,3070],{"class":993},"    alice",[938,3072,1602],{"class":948},[938,3074,3056],{"class":973},[938,3076,3059],{"class":948},[938,3078,3080],{"class":940,"line":3079},38,[938,3081,1072],{"class":948},[923,3083,3084,3085,3087],{},"最后的代码中，我把 Bob 放在了更小的作用域内，这样 Bob 会比 Alice 更早释放。Bob 释放后，试图获取 Alice 的 ",[919,3086,2400],{}," 成员就会得到空指针。",[3089,3090,3091],"blockquote",{},[923,3092,3093,3094,3096,3097,3099,3100,3102,3103,2469,3105,3107],{},"为了保证所有的 ",[919,3095,2419],{}," 在资源释放后还可以继续工作，",[919,3098,921],{}," 同时需要维护控制块的生存期。简单来说，控制块中除了包含引用计数，还要包含“弱计数”（Weak count），即目前有多少 ",[919,3101,2419],{}," 指向这个控制块。只有当弱计数降为 0 的时候，",[919,3104,921],{},[919,3106,2419],{}," 才会释放控制块。",[3109,3110,3111],"style",{},"html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}",{"title":934,"searchDepth":941,"depth":959,"links":3113},[3114],{"id":1239,"depth":959,"text":1239},"std::sharedptr 是具有共享所有权的智能指针。","md",null,{},{"icon":746},{"title":760,"description":3115},"4HPFrXck3RkM2M0gP7_le_OgJ50DmDqcCxiACnoLu_Y",[3123,3124],{"title":756,"path":757,"stem":758,"description":756,"icon":746,"children":-1},{"title":764,"path":765,"stem":766,"description":3125,"icon":746,"children":-1},"特殊成员函数是一种约定俗成的说法，一般指编译器会自行生成的那些预置成员函数。",1784618139148]