zoukankan      html  css  js  c++  java
  • 使用Boost库中的组件进行C++内存管理

    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

    类部分摘抄
    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;
    }
    


  • 相关阅读:
    selenium--下拉列表选择
    Java——基本类型包装类,System类,Math类,Arrays类,BigInteger类,BigDecimal类
    Java——Object类,String类,StringBuffer类
    Java——面向对象进阶(final关键字,static关键字,匿名对象,内部类,四种访问修饰符,代码块)
    Java——面向对象进阶(构造方法,this,super)
    Java——面向对象进阶(抽象类,接口)
    Java——面向对象编程
    java——类型转换,冒泡排序,选择排序,二分查找,数组的翻转
    CentOS7下安装MySQL
    Java——定义类,引用类数据类型,集合类型(array list)
  • 原文地址:https://www.cnblogs.com/dyllove98/p/3190125.html
Copyright © 2011-2022 走看看