何时需要使用智能指针:
1. 资源所有权共享。
a) 如果多个对象需要同时使用第三个对象时,就需要知道这第三个对象是何时释放的,释放的时机要正确。
2. 要编写异常安全的代码时。
a) 就是当异常被抛出时没有资源泄露并保证程序状态的一致性。
3. 避免常见的错误,如资源泄露。
a) 如忘记delete操作等。
Smart_ptr库如何改进你的程序:
智能指针解决了资源生存期管理的问题(尤其是动态分配的对象),不同种类的智能指针风格不同,但都有一个共性,那就是自动资源管理。
1. shared_ptr:进行对象的生存期管理,使得分享资源的所有权变得有效且安全。
2. weak_ptr:可以很安全的观测共享资源,避免了悬挂的指针。
3. scoped_ptr和scoped_array限制了资源的适用范围,使得代码更容易编写和维护,并有助于写出异常安全的代码。
:
五个常用的指针:
shared_ptr、scoped_ptr、weak_ptr、intrusive_ptr、auto_ptr(不能作为容器的元素)。
scoped_ptr:
头文件:”boost/scoped_ptr.hpp”
Boost::scoped_ptr用于确保动态分配的对象能够被正确删除。scoped_ptr有着和auto_ptr相似的特性,最大的区别就是它不能转让所有权而auto_ptr可以。事实上boost::scoped_ptr永远不能被复制和赋值。它对自己的所有权永不放弃。
总结:使用裸指针来写异常安全和无错误的代码是很复杂的。使用智能指针来自动把动态分配对象的生存期限制在一个明确的范围之内,是解决这种问题的有效办法。并且提高了代码的可读性,可维护性和质量。
scoped_ptr的使用范围:
1. 有可能在异常抛出的作用域里使用指针
2. 函数里有几条控制路径
3. 动态分配对象的身生存期应被限制于特定的作用域内
4. 异常安全非常重要。
shared_ptr(不能被显式的删除):
shared_ptr可以从一个裸指针、另一个shared_ptr,一个std::auto_ptr、或者一个boost::weak_ptr构造。还可以传递第二个参数给shared_ptr的构造函数,它被称为构造器。
shared_ptr的使用范围:
1. 当有多个使用者使用同一个对象,而没有一个明显的拥有者。
2. 要把指针存入标准容器时
3. 当要传送对象到库或从库获取对象,而没有明确的所有权时。
4. 当管理一些需要特殊清楚方式的资源时。
#include "boost/scoped_ptr.hpp"
#include "boost/shared_ptr.hpp"#include <string>#include <iostream>#include <cassert>/*void scoped_vs_auto(){ using boost::scoped_ptr; using std::auto_ptr; scoped_ptr<std::string> p_scoped(new std::string("hello")); auto_ptr<std::string>p_auto(new std::string("world")); p_scoped->size(); p_auto->size(); scoped_ptr<std::string>p_another_scoped = p_scoped; auto_ptr<std::string> p_another_auto = p_auto; p_another_scoped->size(); (*p_auto).size();}*/class A{ boost::shared_ptr<int>no_;public: A(boost::shared_ptr<int>no):no_(no){} void value(int i) { *no_=i; }};class B{ boost::shared_ptr<int>no_;public: B(boost::shared_ptr<int>no):no_(no){} int value()const { return *no_; }};int main(){ boost::scoped_ptr<std::string>p(new std::string("hello world xiaofeng.")); if ( p ) { std::cout<< *p << std::endl; } size_t i = p->size(); *p = "hello world !!!"; boost::shared_ptr<int> temp(new int(14)); A a(temp); B b(temp); a.value(28); assert(b.value() == 28); //scoped_vs_auto(); return 0;}