zoukankan      html  css  js  c++  java
  • boost--smart_ptr库

    C++没有类似Java、C#等语言的垃圾回收机制,内存管理是最为头痛的工作。
    new、delete以及指针的不恰当运用是C++中造成资源获取/释放问题的根源。
    智能指针是解决这些问题的一种方案,boost.smart_ptr库提供了六种智能指针,包括:
    scoped_ptrscoped_arrayshared_ptrshared_arrayweak_ptrintrusive_ptr
    它们都是轻量级对象,速度与原始指针相差无几,都是异常安全的。

    要使用smart_ptr组件,需要包含头文件 #include <boost/smart_ptr.hpp>

    shared_ptr是一个最像指针的“智能指针”,是boost.smart_ptr库中最有价值、最重要的组成部分。已收入了C++11标准。
    shared_ptr是引用计数的智能指针,可以被自由的拷贝和赋值,在任意地方共享它,当没有代码使用(引用计数为0)时删除被包装的动态分配的对象。

    shared_ptr可以安全的放到标准容器中,是在STL容器中存储指针的最标准解法。

    应用举例:

    #include "stdafx.h"
    #include <iostream>
    #include <cassert>
    #include <string>
    #include <vector>
    #include <boost/smart_ptr.hpp>
    
    using std::cout;
    using std::endl;
    using std::string;
    using std::vector;
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	boost::scoped_ptr<string> pstr(new string("scoped_ptr test"));
    	assert(pstr);
    	assert(pstr != nullptr);
    	*pstr = "hello test";
    	cout << *pstr << ": " << pstr->size();
    
    	boost::scoped_ptr<string> another_p_str;
    	assert(!another_p_str);
    
    	if (NULL == another_p_str)
    	{
    		cout << "
    Null pointer!
    ";
    	}
    
    	boost::shared_ptr<string> sps(boost::make_shared<string>("shared_ptr_test"));
    	cout << "
    " << sps->c_str() << endl;
    	boost::shared_ptr<string> sps2(sps);
    	*sps2 = "shared_ptr is smart!";
    	cout << *sps << endl;
    
    	assert(sps == sps2);
    
    	//shared_ptr用于容器
    	typedef vector<boost::shared_ptr<int>> VSI;
    	VSI v;
    	v.push_back(boost::make_shared<int>(1));
    	v.push_back(boost::make_shared<int>(2));
    	v.push_back(boost::make_shared<int>(3));
    	v.push_back(boost::make_shared<int>(4));
    	v.push_back(boost::make_shared<int>(5));
    
    	cout << "
    Vevtor: ";
    	boost::shared_ptr<int> pv = v[0];
    	*pv = 1000;
    	for (size_t i = 0; i < v.size(); ++i)
    	{
    		cout << *v[i] << " ";
    	}
    	return 0;
    }
    

    在开发实践中,个人觉的最应当使用智能指针的两种场合:
    (1) 应用于标准容器
    在使用容器管理大量对象指针的时候,必须编写额外的大量代码来保证指针最终被正确释放,通常很麻烦而且容易出错。将shared_ptr作为容器的元素,如vector<shared_ptr<T> >,与存储原始指针的容器所能实现的功能几乎一样,而不用担心资源泄漏。

    (2) 应用于工厂模式
    在程序中编写自己的工厂类或者工厂函数时,通常需要在堆上使用new动态分配一个对象然后返回对象的指针。这种做法很不安全,应为很容易忘记对指针调用delete。
    使用shared_ptr可以解决这个问题,只需要修改工厂方法的接口,不再返回一个原始指针,而是返回一个被shared_ptr包装的智能指针,这样可以很好地保护系统资源,而且会更好地控制对接口的使用。

    使用代码来解释shared_ptr应用于工厂模式的用法:

    #ifndef OPERATION_H_
    #define OPERATION_H_
    #include <boost/smart_ptr.hpp>
    
    enum OperationType
    {
    	ADD,
    	SUB,
    	MUL,
    	DIV
    };
    
    //运算基类
    class Operation
    {
    public:
    	virtual double GetResult() const = 0;
    
    	Operation()
    		: m_Operand1(0.0)
    		, m_Operand2(0.0)
    	{
    
    	}
    
    	void SetOperrand1(const double operand1)
    	{
    		m_Operand1 = operand1;
    	}
    	double GetOperand1() const
    	{
    		return m_Operand1;
    	}
    
    	void SetOperrand2(const double operand2)
    	{
    		m_Operand2 = operand2;
    	}
    	double GetOperand2() const
    	{
    		return m_Operand2;
    	}
    
    protected:
    	virtual ~Operation(){}
    
    protected:
    	double m_Operand1;
    	double m_Operand2;
    };
    //加法
    class Add : public Operation
    {
    public:
    	double GetResult() const override;
    };
    //减法
    class Sub : public Operation
    {
    public:
    	double GetResult() const override;
    };
    //乘法
    class Mul : public Operation
    {
    public:
    	double GetResult() const override;
    };
    //除法
    class Div : public Operation
    {
    public:
    	double GetResult() const override;
    };
    
    //工厂类
    class OperationFactory
    {
    public:
    	static boost::shared_ptr<Operation> CreateOperation(OperationType type)
    	{
    		boost::shared_ptr<Operation> oper;
    		switch (type)
    		{
    		case ADD:
    			oper = boost::make_shared<Add>();
    			break;
    		case SUB:
    			oper = boost::make_shared<Sub>();
    			break;
    		case MUL:
    			oper = boost::make_shared<Mul>();
    			break;
    		case DIV:
    			oper = boost::make_shared<Div>();
    			break;
    		default: ;
    		}
    		return oper;
    	}
    };
    
    
    #endif
    

    调用代码:

    //通过工厂方法创建对象
    auto pOper = OperationFactory::CreateOperation(MUL);
    if (nullptr != p)
    {
    	pOper->SetOperrand1(100); //可以像普通指针一样使用
    	pOper->SetOperrand2(123);//不必担心内存泄漏,shared_ptr会自动管理指针
    	cout << "
    " << pOper->GetResult();
    }
    

    C++11标准中std::shared_ptr,功能与boost::shared_ptr基本相同,完全可以定价互换。
    包含头文件#incude <memory>

  • 相关阅读:
    jmeter(46) redis
    jmeter(45) tcp/ip协议
    Codeforces Round #538 (Div. 2)D(区间DP,思维)
    Codeforces Global Round 1D(DP,思维)
    Educational Codeforces Round 57D(DP,思维)
    UPC11073(DP,思维)
    Yahoo Progamming Contest 2019D(DP,思维)
    Atcoder Beginner Contest 118D(DP,完全背包,贪心)
    Xuzhou Winter Camp 1C(模拟)
    Educational Codeforces Round 57 (Rated for Div. 2)D(动态规划)
  • 原文地址:https://www.cnblogs.com/cmranger/p/4764947.html
Copyright © 2011-2022 走看看