1.如果delete object的某个动作被省略过去,泄露的不仅是对象的那一块内存,还包括对象保存的任何资源。为了确保资源总会被释放,我们需要把资源放进对象,当控制流离开这个对象,其析构函数来自动释放那些资源。一种方式是auto_ptr(会使得被复制物指向null)。这种获得资源后立刻放进管理对象的观念被称为RAII:resource aquisition is initialization。更进一步,如果有多个指针指向同一个资源就应当使用引用计数型指针,即智慧指针。由于shared_ptr析构函数的删除动作是delete而不是delete[],因此shared_ptr指向string或者vector时是一个有瑕疵的动作,此时我们要自定义一个lambda表达式。
2.很多时候对RAII对象的复制并不合理,比如对象中含MUTEX,析构函数总使用unlock()时,应该禁止这个对象被复制,因此可以使用前文条款禁止copying行为。
3.有时候我们希望保有资源直到最后一个对象被销毁,可以使用引用计数的方法,而很不幸的是shared_ptr的删除器缺省行为是删除其所指物,这个缺省行为可能并不是那么恰当,因为我们可以是想释放锁定而非删除资源。但是shared_ptr允许指定所谓的删除器,因此可以指定unlock()函数作为删除器,这样就可以释放锁定而不删除资源了。除此之外,如果实在需要这个资源也可以对资源实现深度拷贝,或者像auto_ptr一样彻底转移资源的所有权。
4.尽管智能指针可以通过->或者*来读取资源,但是仍然存在有些应用API希望获得原始指针,而并非shared_ptr。此时智能指针应当提供这样的访问机会(get()函数),但是仍然会有人觉得这样是一种很麻烦的范式而不愿意再使用智能指针(比如说我),从而导致了资源泄露的可能性。上述get()函数的方式是显式转换,还可以有隐式转换的方式:在类中定义一个operator func().
5.成对使用delete和new时,两者的形式要对应起来。否则delete时,难以知道所指的对象是单一对象还是对象数组。调用new时使用[]则调用delete时也要使用[],如果new不使用[],那么delete也不需要使用[]。
6.已独立的语句新建好对象之后,再把这个对象存入智能指针之内,否则笼统的写法譬如func1(shared_ptr<typeA>name(new typeB),func2),此时编译器可能会有预期之外的执行次序的自由,比如执行new->func2(万一崩溃)->shared_ptr。
本文探讨了智能指针在C++中的作用,强调了RAII(Resource Acquisition Is Initialization)原则的重要性,用于确保资源在对象生命周期结束时得以释放。介绍了auto_ptr和shared_ptr的使用,特别是shared_ptr在处理string和vector时可能存在的问题以及解决方案。同时,讨论了如何通过禁止复制防止资源误操作,以及如何利用删除器定制资源释放行为。此外,提到了智能指针与原始指针之间的转换需求,以及在API交互中可能存在的风险。最后,文章提醒了new和delete操作的一致性,以避免对象数组的管理错误。
2482

被折叠的 条评论
为什么被折叠?



