使用Boost库中的组件进行C++内存管理
2013-07-14 22:41
477 查看
C++标准库中的auto_ptr,智能指针,部分的解决了获取资源自动释放的问题
在Boost中,提供了6中智能指针:scoped_ptr, scoped_array, shared_ptr, shared_array, weak_ptr, instrusive_ptt,这些智能指针属于smart_ptr组件
使用时: #include <boost/smart_ptr.hpp> using namespace std;
接下来介绍前四个智能指针
scoped_ptr:是一个很类似auto_ptr的智能指针,它包装了new操作符在堆上分配的动态对象,能够保证动态创建的对象在任何时候都可以被正确的删除,但是scoped_ptr的所有权不能被转移,一旦scoped_ptr会获得了对象的管理权,你就无法再从它那里取回来。因为scoped_ptr同时将拷贝构造函数和赋值操作符都声明为私有的(只在本作用域里使用,不希望被转移)
(摘抄于深入C++“准标准库”)
scoped_array,它包装了new[]操作符在堆上分配的动态数组,为动态数组提供了一个代理,保证可以正确的释放内存
主要特点:构造函数接收的指针p必须是new[]的结果,而不是new表达式的结果
没有* ->操作符重载,因为scoped_array持有的不是一个普通的指针
析构函数必须使用delete[] 释放资源,而不是delete
提供operator[]操作符重载,可以像普通数组一样使用下标访问元素
没有begin,end等类似容器的迭代器操作函数
用法
更像‘智能指针“,与scoped_ptr一样包装了new操作符在堆上分配的动态对象,但它的实现是引用计数型的智能指针,可以被自由的拷贝和复制,在任意的地方共享它,当没有代码使用(引用计数为0)它时才删除被包装的动态分配的对象。share_ptr也可以安全的放到标准容器中,并弥补了auto_ptr因为转移语义而不能把指针作为STL容器元素的缺陷
用法
用于标准容器
在Boost中,提供了6中智能指针:scoped_ptr, scoped_array, shared_ptr, shared_array, weak_ptr, instrusive_ptt,这些智能指针属于smart_ptr组件
使用时: #include <boost/smart_ptr.hpp> using namespace std;
接下来介绍前四个智能指针
scoped_ptr
类部分摘抄template<class T> class scoped_ptr // noncopyable { private: T * px; scoped_ptr(scoped_ptr const &); scoped_ptr & operator=(scoped_ptr const &); typedef scoped_ptr<T> this_type; void operator==( scoped_ptr const& ) const; void operator!=( scoped_ptr const& ) const; public: typedef T element_type; explicit scoped_ptr( T * p = 0 ): px( p ) // never throws { #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) boost::sp_scalar_constructor_hook( px ); #endif } #ifndef BOOST_NO_AUTO_PTR explicit scoped_ptr( std::auto_ptr<T> p ): px( p.release() ) // never throws { #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) boost::sp_scalar_constructor_hook( px ); #endif } #endif ~scoped_ptr() // never throws { #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) boost::sp_scalar_destructor_hook( px ); #endif boost::checked_delete( px ); }
。。。。。
摘抄与boost/smart_ptr/scoped_ptr.hpp中
scoped_ptr:是一个很类似auto_ptr的智能指针,它包装了new操作符在堆上分配的动态对象,能够保证动态创建的对象在任何时候都可以被正确的删除,但是scoped_ptr的所有权不能被转移,一旦scoped_ptr会获得了对象的管理权,你就无法再从它那里取回来。因为scoped_ptr同时将拷贝构造函数和赋值操作符都声明为私有的(只在本作用域里使用,不希望被转移)
#include <boost/smart_ptr.hpp> #include <iostream> #include <cassert> using namespace boost; using namespace std; struct posix_file { //一个示范的文件类 posix_file(const char *file_name) { cout << "open file: " << file_name << endl; } ~posix_file() { cout << "close file" << endl; } }; int main(void) { scoped_ptr<int> p(new int); //一个int指针的scoped_ptr if(p) { *p=100; cout << *p << endl; } p.reset(); //reset()置空scoped_ptr assert(p==0); if(!p) { cout << "scoped_ptr==null" << endl; } scoped_ptr<posix_file> fp(new posix_file("/tmp/a.txt")); auto_ptr<int> ap(new int(10)); //一个int的自动指针 scoped_ptr<int> sp(ap); assert(ap.get() == 0); //原auto_ptr不再拥有指针 ap.reset(new int(20)); cout << *ap << "," << *sp << endl; auto_ptr<int> ap2; ap2=ap; //ap2从ap获得原始指针,发生所有权转移 assert(ap.get()==0); //scoped_ptr<int> sp2; //sp2=sp; //赋值操作错误 return 0; }
(摘抄于深入C++“准标准库”)
scoped_array
类部分摘要template<class T> class scoped_array // noncopyable { private: T * px; scoped_array(scoped_array const &); scoped_array & operator=(scoped_array const &); typedef scoped_array<T> this_type; void operator==( scoped_array const& ) const; void operator!=( scoped_array const& ) const; public: typedef T element_type; explicit scoped_array( T * p = 0 ) : px( p ) // never throws { #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) boost::sp_array_constructor_hook( px ); #endif } ~scoped_array() // never throws { #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) boost::sp_array_destructor_hook( px ); #endif boost::checked_array_delete( px ); }
。。。。
scoped_array,它包装了new[]操作符在堆上分配的动态数组,为动态数组提供了一个代理,保证可以正确的释放内存
主要特点:构造函数接收的指针p必须是new[]的结果,而不是new表达式的结果
没有* ->操作符重载,因为scoped_array持有的不是一个普通的指针
析构函数必须使用delete[] 释放资源,而不是delete
提供operator[]操作符重载,可以像普通数组一样使用下标访问元素
没有begin,end等类似容器的迭代器操作函数
用法
#include <boost/smart_ptr.hpp> using namespace boost; using namespace std; int main(void) { int *arr = new int[100]; scoped_array<int> sa(arr); //fill_n(&sa[0], 100, 5); //用标准库函数赋值 fill(&sa[0], &sa[99], 5); sa[10] = sa[20]+sa[30]; //只能用operator[]来访问数组元素 cout << sa[10] << endl; //cout << *(sa+20) << endl; //没有* ->运算符 return 0; }
shared_ptr
类部分摘要:template<class T> class shared_ptr { private: // Borland 5.5.1 specific workaround typedef shared_ptr<T> this_type; public: typedef T element_type; typedef T value_type; typedef T * pointer; typedef typename boost::detail::shared_ptr_traits<T>::reference reference; shared_ptr(): px(0), pn() // never throws in 1.30+ { } template<class Y> explicit shared_ptr( Y * p ): px( p ), pn( p ) // Y must be complete { boost::detail::sp_enable_shared_from_this( this, p, p ); } // // Requirements: D's copy constructor must not throw // // shared_ptr will release p by calling d(p) // template<class Y, class D> shared_ptr(Y * p, D d): px(p), pn(p, d) { boost::detail::sp_enable_shared_from_this( this, p, p ); } // As above, but with allocator. A's copy constructor shall not throw. template<class Y, class D, class A> shared_ptr( Y * p, D d, A a ): px( p ), pn( p, d, a ) { boost::detail::sp_enable_shared_from_this( this, p, p ); }
更像‘智能指针“,与scoped_ptr一样包装了new操作符在堆上分配的动态对象,但它的实现是引用计数型的智能指针,可以被自由的拷贝和复制,在任意的地方共享它,当没有代码使用(引用计数为0)它时才删除被包装的动态分配的对象。share_ptr也可以安全的放到标准容器中,并弥补了auto_ptr因为转移语义而不能把指针作为STL容器元素的缺陷
用法
class shared { public: shared(shared_ptr<int> p_) : p(p_) {} //构造函数初始化成员变量 void print() { cout << "count: " << p.use_count() << "v = " << *p << endl; } private: shared_ptr<int> p; }; void print_func(shared_ptr<int> p) { cout << "count: " << p.use_count() << "v = " << *p << endl; } int main(void) { shared_ptr<int> p(new int(10)); shared s1(p), s2(p); s1.print(); s2.print(); *p=20; print_func(p); s1.print(); return 0; }
用于标准容器
int main(void) { typedef vector<shared_ptr<int> > vs; vs v(10); int i=10; for (vs::iterator pos=v.begin(); pos!=v.end(); pos++) { *pos = make_shared<int>(++i); cout << *(*pos) << " "; } cout << endl; shared_ptr<int> p = v[9]; *p = 100; cout << *v[9] << endl; return 0; }
相关文章推荐
- 使用Boost库中的组件进行C++内存管理
- C++中std::tr1::function和bind 组件的使用 和 以boost::function和boost:bind取代虚函数
- 在服务器上使用第三方独立组件对Word/Excel进行编程
- C++_使用C++代码进行MD5加密
- 使用JNI在JAVA和C++之间进行交互操作
- C++boost库之variant使用
- GDAL入门-使用GDAL进行遥感影像NDVI的计算(C++版本)
- 使用JNI进行Java与C/C++语言混合编程(2)--在C/C++中调用Java代码
- dotnet core使用开源组件FastHttpApi进行web应用开发(转)
- 使用ActiveMQ进行C++与C#的通信4 - 使用C++连接ActiveMQ
- C++ 中使用sstream进行string和int相互转换
- 关于C++ Boost库的使用
- 如何使用Valgrind memcheck工具进行C/C++的内存泄漏检测
- 使用ActiveMQ进行C++与C#的通信6 - 相关资源(终)
- C++使用try&catch进行异常处理的简单范例
- 如何在C++中使用cout进行高级的格式化输出操作
- zookeeper使用ACL进行权限控制C++
- 使用 C++ 和 MFC 进行多线程编程
- 【C++】使用sstream头文件进行格式转换
- cocos2d-x 3.7 C++接入GameCenter 使用socket 进行网络数据请求