Boost智能指针
智能指针最早在boost中提出,直到C++11才被正式引入std库。 因此智能智能存在两种,一种是boost命名空间的,一种是std命名空间的,两种不能混用,使用第三方库的时候要注意区分。
用的最多的智能指针。使用引用计数的智能指针,当引用计数为0的时候就释放资源。不过并不是线程安全的。当然,多线程读写的时候注意加锁就可以了。
std::unique_ptr<T>
一个指针智能指向一个对象的指针,不能拷贝,但可以使用std::move转移。
指针的转移:std::unique_ptr<int> b = std::move(a);
std::auto_ptr<T>
据说不是太好用,并且不能不能转移所有权,不能放在stl容器中,不能指向数组。这个东西被C++11废弃了,unique_ptr能够代替它的功能。
空指针
判断:
直接判断是否为nullptr就可以了,如:
std::sharedptr<int> a;
if(a == nullptr) a.reset(new int);
赋值:
不能使用NULL或者nullptr赋值空指针,空指针应该是std::shared_ptr<T>(),参数为空即为空指针。
其实更好的是p.reset();
创建智能指针
std::shared_ptr<int> p; p.reset(new int); // reset重新赋值
std::shared_ptr<int> p = std::make_shared<int>();
std::shared_ptr<int> p(new int); // 结果同上, 但是多拷贝一次, 速度较慢
std::shared_ptr<int> q = std::make_shared<int>(*p); // 拷贝*p的一个智能指针q(至于是深拷贝还是浅拷贝就取决于该类型的拷贝构造函数了)
std::shared_prt<int> q(p.get()); // 用p中的指针对象创建q,这是一种错误的用法, 这将导致p和q在析构的时候同时delete同一个空间而崩溃.
获取实际指针
p.get();
修改指针
指定新的对象:p.reset(new int);
清空内部对象:p.reset();
修改老代码的指针为智能指针
其实这是非常容易的,由于智能指针重载了->操作符,因此除了赋值和delete之外的操作都完全兼容。
如,将如下代码改为智能指针:
class A; A* pA; pA = new A(); if(pA != nullptr) { pA->func1(); pA->func2(); } func(pA); delete pA;
改为智能指针后如下:
class A; std::shared_ptr<A> pA; pA.reset(new A()); if(pA != nullptr) { pA->func1(); pA->func2(); } func(pA.get()); // 注意func中不能有delete指针的操作, 最好是把func的接口也改成智能指针 //delete pA; 这里不需要手动delete了