智能指针的理解

智能指针是利用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...

 

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值