![](https://img-blog.csdnimg.cn/20201014180756918.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
《白话C++》智能指针专辑
文章平均质量分 76
将《白话C++》中讲智能指针的内容,合到一起
yanzhenxi
这个作者很懒,什么都没留下…
展开
-
《白话C++》第10章 STL和boost,Page105 enable_shared_from_this
然而,foo()函数接过去的那个shared_ptr对象,它也会尝试释放所拥有的裸指针,也就是this,而 *this就是coo_1,而coo_1……让Coo认enable_shared_from_this为父,更是注定Coo必须以智能指针面试,否则程序在运行时将因调用“shared_from_this()”而出错,原因可参考之前的分析,现在先牢记结论:。再注意加粗的“shared_from_this()”,这就是我们继承所得的能力,它保障传递给foo一个正确的shared_ptr原创 2024-02-20 21:43:31 · 890 阅读 · 0 评论 -
《白话C++》第10章 STL和boost,Page101 10.4.6 std::weak_ptr
019行,将一个shared_ptr,赋值给一个弱指针(weak_ptr),并不会造成shared_ptr的引用计数加1。因此后续输出时的内容才会是两个1。那么在函数体中,pcoo不一定一直有效,因为在复杂的并发情况下,foo_ref的调用可能是异步的,调用者可能在foo_ref还没执行完毕就先结束了,从而造成pcoo所引用的shared_ptr失效。但是,并不是说只要是类成员,就一定使用weak_ptr而不使用shared_ptr,恰恰相反,weak_ptr应该只用在可以打破循环的某一环皆可。原创 2024-02-20 18:22:00 · 913 阅读 · 0 评论 -
《白话C++》第10章 STL和boost,Page98 10.4.6 std::weak_ptr
除了pc2自身在管理c2以外,还有c1的成员数据_c2(另一个智能指针)也在c2,因此计数为2。类似的故事发生在它身上,最后它深情地对c1说:“我先走了,你要继续好好活着,c2家里的_c1是爱你的。而当我们说智能指针所管理的指针(或对象)时,说的是它所拥有的裸指针或裸指针所指向的内存中存放的对象,比如例中的c1和c2。强调一下:当我们说“智能指针”对象时,我们说的是智能指针本身,比如上例代码中的pc1和pc2,这两个智能指针对象,它们本身是栈对象(不靠new产生),它们会自动析构。原创 2024-02-20 14:12:41 · 820 阅读 · 0 评论 -
《白话C++》第10章 STL和boost,Page97 shared_ptr管理数组
若采用不支持17新标的编译器,该代码也可以编译通过,但释放时采用的是delete,而非delete[ ]。如果你无法使用17新标,可以借助shared_ptr提供的第二个入参,以指定如何释放对象。用上C++ 17甚至更高标准的编译器,上述烦恼应该就不存在了。原创 2024-02-20 10:12:46 · 436 阅读 · 2 评论 -
《白话C++》第10章 STL和boost,Page92 并发下shared_ptr实例
不过,我们这打印机是半自动的,光把数据塞入只是让“打印机”记下数据,想要打印出来,需要不断地调用PrintOne()方法,正如它的名字,这个方法每次把打印机队列中排在最前头的数据取出,执行打印。for循环语句域内,每循环一次,都会创建一个data(shared_ptr),然后销毁它,但它并不会真正地去释放所持有的DataABC堆对象,因为在析构之前,该智能指针已经通过函数传递的方式,共享给另一个智能指针,那个智能指针继续传递,进入Printer对象的队列中存着,一直到另外一线程将它“抓”出去打印。原创 2024-02-20 09:36:37 · 802 阅读 · 0 评论 -
《白话C++》第10章 STL和boost,Page91 std::shared_ptr常用功能03
不是很重要,但也提一下,通常使用make_shared创建shared_ptr,会比先创建裸指针,再创建shared_ptr性能略好。make_shared()是一个函数,因此返回的智能指针可以妥妥地运用转移语义,所以此时在定义p时回到使用“=”进行初始化的传统形式(编译器在这里用了优化手段)。标准库提供了make_shared方法,,可以创建出shared_ptr,不需要字面上的new操作。make_shared是个模版函数,支持不定个数的入参,内部则调用所要创建的对象的构造函数,并匹配入参。原创 2024-02-19 21:39:38 · 409 阅读 · 0 评论 -
《白话C++》第10章 STL和boost,Page88 std::shared_ptr常用功能02
名字中间都插入了“pointer”,不过其实只用于处理shared_ptr类型,作用和各自去除pointer的转换操作类似:“static”版和“dynamic”版都可用于基类和派生类指针之间的双向转换,前者不作正确性检查,后者会在运行时尝试检查。“const”则用于处理常量和非常量指针(指智能指针所拥有的裸指针)之间的强制转换。这很合清理,尽管B和D1是基类和派生类的关系,但将二者套入shared_ptr<T>之后,不能说shared_ptr<B>和shared_ptr<D1>也有派生关系。原创 2024-02-19 20:53:48 · 936 阅读 · 0 评论 -
《白话C++》第10章 STL和boost,Page85 std::shared_ptr常用功能
做法很简单:如果你有一个裸指针需要使用shared_ptr管理,就确保一开始只用一个shared_ptr对象在创建时托管该裸指针,然后从第二个shared_ptr开始,就只从之前的shared_ptr拷贝构建。注意,此时sia和sib的状态是“它们管理着共同的裸指针”,而非我们所要的“它们共同管理同一个裸指针”,此时sia中的引用计数是1,而sib也一样,二者中任何一个结束生命周期,都会去释放pi所指向的内存。关键是sib的构建,它的构造入参也是裸指针pi,而不是同类sia。此时它和pa、pb没有关系。原创 2024-02-19 17:10:56 · 923 阅读 · 0 评论 -
《白话C++》第10章 STL和boost,Page84 shared_ptr示例使用,容器中的指针
先往list中添加5个新建的BigS堆对象(指针),然后将这些指针再赋值到另一个容器vector中。最后清空两个容器,结果看到调用5次的~BigS()析构,不少不多,看起来好像是lst和vec很有默契的配合,已达成谁后面清空谁负责,其实真正调用delete操作的是容器中的智能指针,关容器什么事?容器中的指针在容器解体时经常忘了释放?指针存放在容器中多次,结果被重复释放?原创 2024-02-19 14:16:10 · 430 阅读 · 0 评论 -
《白话C++》第10章 STL和boost,Page84 让MySharedPtr持有一个用户自定义的类,尝试输出更加详细的信息。
【代码】《白话C++》第10章 STL和boost,Page84 让MySharedPtr持有一个用户自定义的类,尝试输出更加详细的信息。原创 2024-02-19 13:53:11 · 370 阅读 · 0 评论 -
《白话C++》第10章 STL和boost,Page78 10.4.5 std::shared_ptr
不行,unique_ptr包装下的指针不能复制,决定了某个指针一旦采用push_back(move(p))的语法加入列表(其中p的类型是unique_ptr <int>),p所拥有的裸指针将变成空指针,后续对它的取值,就是在访问非法内存。shared_ptr的思路是:另弄一个计数,记录待管理的那块内存到底有几个指针指向它,每当有个指针要被释放前,通过计数检查它是不是最后一个指向该内存的指针,如果不是,就不真正释放内存,只是将计数减一,如果是则释放内存。根据推理,此时引用计数减为1,裸指针没有被杀出。原创 2024-02-19 12:14:37 · 827 阅读 · 0 评论 -
《白话C++》第10章 STL和boost,Page74 10.4.4 std::unique_ptr
原始的堆数组,它其实就是一个指针,除了靠自行记忆,当我们手上有一个指针,除非搞“黑科技”,否则我们还真不能识别出它是指向一个对象,还是指向一组对象,如果是后者,更无法得知所指向的数组有多大。此时调用处的代码明确写着“move”,这也是对调用者最好的提醒:你定义的upi所管理的内存,已经被转移走了,因此upi内部裸指针已经是nullptr了,请不要再访问它了。第二个,unique_ptr改进的是,auto_ptr最大的黑暗面:“偷偷摸摸”的,看似“复制”其实却是“转移”的操作。原创 2024-02-18 20:55:22 · 895 阅读 · 0 评论 -
《白话C++》第10章 STL和boost,Page73~74 boost::scoped_array
此时我们可以使用vector,这样可动态扩大容量,自动管理内存申请和释放的容器,也可以使用原始的new[ ]操作。boost::scoped_array同样提供“reset(T *p = 0)”操作,其作用释放原有裸素组并拥有新的裸数组(p的声明虽然是指针形式,但那是因为作为函数入参,数组发生了“褪化”)。这行代码可以通过编译,但最后自动释放时,至少会出现99个 sizeof(int)的内存泄漏,scoped_ptr在释放时使用的是 “delete” 操作,而非此时希望的 “delete[ ]”原创 2024-02-18 16:55:45 · 359 阅读 · 0 评论 -
《白话C++》第10章 STL和boost,Page70~72 boost::scoped_ptr
泛型》篇中提到的某个IT项目的辩论会,一派坚持智能指针和裸指针可以“离婚”,它们是std::auto_ptr的支持者,原创 2024-02-17 17:35:04 · 416 阅读 · 0 评论 -
《白话C++》第10章 STL和boost,Page67~70 std::auto_ptr
【代码】《白话C++》第10章 STL和boost,Page67 std::auto_ptr。原创 2024-02-17 12:29:23 · 379 阅读 · 0 评论 -
《白话C++》第9章 泛型,Page847~849 AutoPtr 允许从外部指针构造
这个版本的AutoPtr仍然还有很多不完美的地方,比如它在构造函数中,一定要new出一个对象,因此无法表达一个“空指针”,也无法“接管”一个已经存在的外部指针,另外,两个(同质的)AutoPtr对象之间,如何赋值,靠被也未实现。原创 2024-02-17 11:00:32 · 411 阅读 · 0 评论 -
《白话C++》第9章 泛型,Page845~847 AutoPtr 模仿裸指针(未完成)
【代码】《白话C++》第9章 泛型,Page845~847 AutoPtr 模仿裸指针。原创 2024-02-16 23:36:11 · 407 阅读 · 0 评论 -
《白话C++》第9章 泛型,Page842~844 9.4.2 AutoPtr
C++编程中,最容易出的问题之一,就是内存泄露,而new一个对象,却忘了delete它,则是造成内存泄露的主要原因之一。原创 2024-02-16 21:56:52 · 404 阅读 · 0 评论 -
第7章 Page449~451 7.8.9智能指针 std::shared_ptr
严格来讲是管理同一个裸指针,那么问题来了,p2和p1同时管理同一个裸指针,接着p1结束生命,自动释放该裸指针,再接着p2也结束生命,于是再次释放该裸指针,不就造成一个指针被释放两次的结果吗?“std::shared_ptr”采用了相当复杂的技术来保证,当存在多个智能指针共同管理某一裸指针,仅当最后一个智能指针结束生命时,才会真正释放所共享的裸指针。将共享式智能指针A赋值给共享式智能指针B,B将与A管理同一个裸指针,并且在系统某处记录,当前有两个智能指针在管理某一裸指针,简称“计数为二”。原创 2024-02-16 21:22:30 · 850 阅读 · 0 评论 -
第7章 Page449 7.8.9智能指针 std::unique_ptr课堂作业,使用智能指针改写foo()函数
【代码】第7章 Page449 7.8.9智能指针 std::unique_ptr课堂作业,使用智能指针改写foo()函数。原创 2024-02-16 15:08:43 · 406 阅读 · 0 评论 -
第7章 Page446~449 7.8.9智能指针 std::unique_ptr
其中的“”指明它所指向的数据类型是“O”。除了创建方法不太一样,以及不用手工释放之外,智能指针使用上和它所管理的裸指针基本一样。例中的裸指针同样没有名字,在调用智能指针对象的构造函数是,直接使用new生成。如果健忘而负责任的程序员,忘了p是智能指针,写出“delete p”这样的代码,也不用怕,编译器会就出这个错误。名字透露身份,“unique_ptr”是“独占式智能指针”。以上都是让智能指针尽量用起来像裸指针的设计。既要让它用起来就像一个裸指针,又要在关键的地方提醒一下你,它不是一个真的指针。原创 2024-02-16 12:35:37 · 397 阅读 · 0 评论 -
第7章 Page442~446 7.8.9智能指针
使用堆数据有以下几个目的(也可称为作用)如表7-18所列。int* p//全局变量。原创 2024-02-16 00:42:10 · 411 阅读 · 0 评论