简介
- 使用shared_ptr 进行对象的生存期自动管理,使得分享资源所有权变得有效且安全。
- 使用weak_ptr可以安全的观测共享资源,避免了悬挂的指针。
- 使用scoped_ptr 和scoped_array限制资源的使用范围,使得代码更易于编写和维护,并有助于写出异常安全的代码。
智能指针解决了资源生存管理的问题。
scoped_ptr
- scoped_ptr可以确保动态分配的对象可以被正确的删除
- scoped_ptr和标准库的std::auto_ptr很类似,区别在于:scoped_ptr不能转让所有权,即永远不可能被赋值和复制
scoped_ptr成员
namespace boost {
template<typename T> class scoped_ptr : noncopyable {
public:
explicit scoped_ptr(T* p = 0); //构造 注意:p必须是 operate new分配的或者使null,T可以使不完整的
~scoped_ptr(); //T在被销毁时必须时完整的
void reset(T* p = 0); //删除已保存的指针,重新保存p,应尽量少使用此函数,过多的使用说明设计有问题
T& operator*() const; //返回一个被保存指针指向对象的引用,如果没有保存指针,会抛出异常,可以用get函数替换。
T* operator->() const; //返回一个被保存指针指向对象的引用,如果没有保存指针,会抛出异常,可以用get函数替换。
T* get() const; //f返回保存的指针,因为时直接操作裸指针,需小心使用,因为可以返回空指针,可以拿来检测scoped_ptr是否为空。不会抛出异常
void swap(scoped_ptr& b); //交换两个 scoped_ptr的内容,不会抛出异常
};
template<typename T> void swap(scoped_ptr<T> & a, scoped_ptr<T> & b);
}
头文件
<boost\smart_ptr\scoped_ptr.hpp>
使用示列
1.基本用法
#include <boost\smart_ptr\scoped_ptr.hpp>
#include<string>
#include<iostream>
int main(){
//new string() 即 new operater
boost::scoped_ptr<std::string> p(new string("Use scoped_ptr often."));
if(p){
std::cout<<*p<< std::endl;
size_t i = p->size();
*p="Change scoped_ptr data";
}//这里p被销毁,并删除std::string
}
2.和std::auto_ptr的比较
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("Hello"));
p_scoped->size();
p_auto->size();
scoped_ptr<std::string> p_another_scoped = p_scoped; //无法编译,scoped_ptr无法被复制和赋值
auto_ptr<std::string> p_another_auto = p_auto; //赋值成功 并且p_auto会变成empty
p_another_auto->size();
(*p_auto).size(); //对空的对象进行访问,会有内存问题。
}
scoped_ptr和Pimpl用法
//pimpl_sample.hpp
#if !define (PIMPL_SAMPLE)
#define PIMPL_SAMPLE
class pimpl_sample{
// stuct impl 是一个向前申明,他把私有成员和函数放在另一个实现文件中
struct impl;
impl *pimpl;
//使用 boost::scoped_ptr<impl> pimpl_; 替换原来的指针可以避免impl构造函数异常。
public:
pimpl_sample();
~pimple_sample();
void do_something();
};
#endif
//pimpl_sample.cpp
#include "pimpl_sampel.hpp"
#include <string>
#include <iostram>
struct pimpl_sample::impl{
void do_something(){
std::cout<< s_ << std::endl;
}
std::string str_s;
};
pimpl_sample::pimpl_sampe():pimple(new impl)
{
pimple->s = "this is pimpl idiom"
}
pimpl_sample::~pimpl_sample(){
delete pimpl_;
}
void pimpl_sample::do_something(){
pimple->do_something();
}
scoped_ptr 不同于 const auto_ptr
scoped_ptr可以被reset,但const auto_ptr无法修改.
使用场景
- 有可能有异常抛出的作用域里使用指针
- 函数里有几条控制路径
- 动态分配对象的生存周期应该被限制再特定的作用域内
- 异常安全非常重要时