智能指针是利用RAII(Resource Acquisition Is Initialization:资源获取即初始化)来管理资源
1、将堆对象的生存周期用栈对象(智能指针)来管理
2、当new一个堆对象的时候,立刻用智能指针来管理
具体操作:1、在构造函数中进行初始化(用一个指针指向堆对象)
2、在析构函数中用delete来释放对象(由于智能指针是一个栈对象,它作用域结束的时候,)自动调用析构函数,从而调用了delete函数释放了堆对象。
智能指针shared_ptr技术与陷阱:
1、意外延长对象的生命期
因为shared_ptr是强引用,只要有一个指向x对象的shared_ptr存在,该对对象的就不会析构。而shared_ptr又是允许拷贝构造构造和赋值的,如果不小心遗留了一个拷贝,那么对象就永世长存了。
2、shared_ptr是管理共享资源的利器,需要注意循环引用的问题,通常的做法是owner持有了child的shared_ptr,child持有指向owner的weak_ptr.
////////////////////////////////////////////引用计数的使用///////////////
<span style="font-size:18px;">#ifndef DEMO_H_
#define DEMO_H_
#include<iostream>
#include<vector>
#include<boost/scoped_ptr.hpp>
#include <boost/shared_ptr.hpp>
using namespace std;
using namespace boost;
class X1 {
public:
X1() {
cout << "X1..." << endl;
}
~X1() {
cout << "~X1()..." << endl;
}
protected:
private:
};
int main() {
cout << "EEnter main" << endl;
/* {
//boost::scoped_ptr<X1> p1(new X1);
//boost::scoped_ptr<X1> p2(p1);
}
boost::shared_ptr<X1> p2(new X1);
cout<<p2.use_count()<<endl;
boost::shared_ptr<X1> p3=p2;
cout<<p2.use_count()<<endl;
p2.reset();
cout<<p3.use_count()<<endl;
p3.reset();
cout<<"Exiting main.........."<<endl;
*/
/*vector<auto_ptr<X1> > v;
auto_ptr<X1> p(new X1);
v.push_back(p); */ //error:vector中的push_back中传入的参数是const类型的,
//同时调用auto_ptr的operator=函数中传入的参数非const类型,所以接口不一致
// 但是shared_ptr的operator=函数中传入的参数const类型,所以接口一致
vector<boost::shared_ptr<X1> > v;
boost::shared_ptr<X1> p(new X1);
v.push_back(p);
cout << p.use_count() << endl;
return 0;
}
#endif
//auto_ptr<T>不能放置vector中
//但shared_ptr<T>可以放置vector中。</span>
//////////////////////例子一循环引用的使用/////////////
<span style="font-size:18px;">/*
* PtrDemo.cpp
*
* Created on: Jul 18, 2014
* Author: zfs
*/
#include <iostream>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
class Parent;
class Child;
typedef boost::shared_ptr<Parent> parentPtr;
typedef boost::shared_ptr<Child> childPtr;
class Parent {
public:
Parent() {
std::cout << "Parent()" << std::endl;
}
~Parent() {
std::cout << "~Parent()" << std::endl;
}
childPtr child_;
};
class Child {
public:
Child() {
std::cout << "Child()" << std::endl;
}
~Child() {
std::cout << "~Child()" << std::endl;
}
parentPtr parent_;
};
int main() {
parentPtr parent(new Parent);
childPtr child(new Child);
std::cout << "parent:jishu1:" << parent.use_count() << std::endl;
std::cout << "child:jishu1:" << child.use_count() << std::endl;
parent->child_ = child;
child->parent_ = parent;
std::cout << "parent:jishu2:" << parent.use_count() << std::endl;
std::cout << "child:jishu2:" << child.use_count() << std::endl;
return 0;
}</span>
输出结果:
Parent()
Child()
parent:jishu1:1
child:jishu1:1
parent:jishu2:2
child:jishu2:2
总结如下:
注意:由上述结果可知:没有运行析构函数,造成的原因是循环引用引起的,解决方案是有2种:
第一种、手动打破循环引用:child->parent_.reset();or parent->child_.reset();
第二种、使用weakd_ptr解决循环引用的问题。请看如下例子:
//////////////////////例子二//////////////////weakd_ptr的使用////////////////////////////
<span style="font-size:18px;">/*
* weakPtrDemo.cpp
*
* Created on: Jul 18, 2014
* Author: zfs
*/
#include <iostream>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
class Parent;
class Child;
typedef boost::shared_ptr<Parent> parentPtr;
typedef boost::shared_ptr<Child> childPtr;
class Parent {
public:
Parent() {
std::cout << "Parent()" << std::endl;
}
~Parent() {
std::cout << "~Parent()" << std::endl;
}
// childPtr child_;
boost::weak_ptr<Child> child_;
};
class Child {
public:
Child() {
std::cout << "Child()" << std::endl;
}
~Child() {
std::cout << "~Child()" << std::endl;
}
parentPtr parent_;
};
int main() {
parentPtr parent(new Parent);
childPtr child(new Child);
std::cout << "parent:jishu1:" << parent.use_count() << std::endl;
std::cout << "child:jishu1:" << child.use_count() << std::endl;
parent->child_ = child;
child->parent_ = parent;
std::cout << "parent:jishu2:" << parent.use_count() << std::endl;
std::cout << "child:jishu2:" << child.use_count() << std::endl;
//parent->child_.reset();
//child->parent_.reset();
return 0;
}
</span>
输出结果:
Parent()
Child()
parent:jishu1:1
child:jishu1:1
parent:jishu2:2
child:jishu2:1
~Child()
~Parent()
总结如下:
//1、shared_ptr:其强引用,只要有一个引用存在,对象就不能释放
//2、weakd_ptr:其弱引用,并不增加对象的引用计数。但它知道对象是否存在
//如果存在,提升为shared_ptr(强引用)成功
//如果不存在,提升失败。
//3、通过weak_ptr访问对象成员的时候,要提升为shared_ptr;(因为 weak_ptr没有重载operator->运算符而shared_ptr重载operator->运算符,所以提升为shared_ptr才可以访问所要引用的对象)
//////////////////////例子三/////////////shared_ptr和weakd_ptr的综合使用////////////////////////////////
/*
<span style="font-size:18px;">/*
* sharedPtrAndweakPtr.cpp
*
* Created on: Jul 18, 2014
* Author: zfs
*/
#include<iostream>
#include<boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
using namespace std;
class X1 {
public:
X1() {
cout << "X1()" << endl;
}
~X1() {
cout << "~X1()" << endl;
}
void Fun() {
cout << "X1::Fun()........." << endl;
}
};
int main() {
boost::weak_ptr<X1> p;
{
boost::shared_ptr<X1> p2(new X1);
cout << "p2-count1:" << p2.use_count() << endl;
p = p2;
cout << "p2-count2:" << p2.use_count() << endl;
boost::shared_ptr<X1> p3 = p.lock(); //把弱引用提升为强引用
if (!p3) {
cout << "p3:提升失败" << endl;
cout << "p3:object is destroyed" << endl; //提升失败
} else { //提升成功
cout << "p3:提升成功" << endl;
p3->Fun();
}
}
boost::shared_ptr<X1> p4 = p.lock();
if (!p4) {
cout << "p4:提升失败" << endl;
cout << "p4:object is destroyed" << endl; //提升失败
} else {
cout << "p4:提升成功" << endl;
p4->Fun(); //提升成功
}
return 0;
}
</span>
输出结果:
X1()
p2-count1:1
p2-count2:1
p3:提升成功
X1::Fun().........
~X1()
p4:提升失败
p4:object is destroyed
//////////////////////例子四/////scoped_array///////////////////////////////////////////
<span style="font-size:18px;">/*
* scopedArray.cpp
*
* Created on: Jul 18, 2014
* Author: zfs
*/
#include<iostream>
#include<boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/scoped_array.hpp>
#include<boost/scoped_ptr.hpp>
class X {
public:
X() {
std::cout << "X..." << std::endl;
}
~X() {
std::cout << "~X..." << std::endl;
}
};
int main(void) {
boost::scoped_array<X> p(new X[4]);
return 0;
}</span>
输出结果:
X...
X...
X...
X...
~X...
~X...
~X...
~X...