智能指针shared_ptr常使用的一种场景是:智能指针数组,即将多个指针放在同一个容器(比如vector)里。下面代码是将指向队列的智能指针放在容器vector中:
typedef std::deque<double> AglSeq;
typedef boost::shared_ptr<AglSeq> AxisSeqPtr;
typedef std::vector<AxisSeqPtr> N_AxisSeqPtr;
typedef N_AxisSeqPtr::size_type N_AxisSeqPtrIdx;
机器人每个轴的运动角度用一个智能指针来管理,每个智能指针指向一个队列,用来盛放机器人运动轨迹算法计算出的位置角度;机器人有多个轴,所以用一个容器vector来容纳管理轴的所有指针,从而组成了一个指针数组类型N_AxisSeqPtr。
N_AxisSeqPtr nAglSeqPtr;
//初始化
nAglSeqPtr.resize(m);
for (N_AxisSeqPtrIdx idx=0; idx!=m; ++idx)
{
nAglSeqPtr[idx].reset(new AglSeq());
}
//使用
for(unsigned i=0; i<pointNum; ++i)
{
for (N_AxisSeqPtrIdx idx=0; idx!=m; ++idx)
{
nAglSeqPtr[idx]->push_back(rad2deg(posACS(i)));
nAglSeqPtr[idx]->pop_front();
X = nAglSeqPtr[idx]->at(pointNum);
X = nAglSeqPtr[idx]->back();
X = nAglSeqPtr[idx]->front();
nAglSeqPtr[idx]->clear();
nAglSeqPtr[idx]->insert(iterator_p, args);
nAglSeqPtr[idx]->erase(iterator_p);
}
}
......
//重置改变
nAglSeqPtr.resize(n); //不同类型机器人有不同轴数,故需要重置数组大小
for (N_AxisSeqPtrIdx idx=0; idx!=n; ++idx)
{
nAglSeqPtr[idx].reset(new AglSeq()); //重置智能指针的所指对象
}
提出的问题
1. 指针数组resize操作之后,之前的指针所指向的对象还在吗? 还可以继续使用吗?
:参考博客http://blog.youkuaiyun.com/cjfeii/article/details/9247569
vector的成员函数resize分析
resize会调用构造函数来构造一个容器存放类型的临时变量,这里指的是智能指针shared_ptr类临时对象,不妨设为tmpA。
如果__new_size > size(),就进行insert操作;
如果__new_size < size(),就进行erase操作,直接调用相应的析构函数
最后,调用tmpA的析构函数。
2. 智能指针的reset操作是怎样的?
p.reset(new AglSeq())
指针与指向原来对象对应的引用计数减1,若引用计数减为0则释放该对象内存;
指针与指向新对象对应的引用计数加1;p.reset()
指针与指向原来对象对应的引用计数减1,若引用计数减为0则释放该对象内存;
if ( !p.unique() ) //改变前判断是否对象的唯一使用者,若不是则拷贝一份用来修改
{
p.reset( new string( *p ) );
}
*p += newValue;
if ( p.use_count() == 0 ){...} //一般用于调试,是比较耗时的操作time-consuming!!