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>

  • 相关阅读:
    2019西湖论剑网络安全技能大赛(大学生组)部分WriteUp
    C++学习(四十)(C语言部分)之 学生管理系统设计
    C++学习(三十九)(C语言部分)之 游戏项目(2048游戏)
    C++学习(三十八)(C语言部分)之 排序(冒泡 选择 插入 快排)
    C++学习(三十七)(C语言部分)之 链式栈(推箱子实现)
    C++学习(三十六)(C语言部分)之 链表2
    C++学习(三十五)(C语言部分)之 单链表
    C++学习(三十四)(C语言部分)之 链表
    C++学习(三十三)(C语言部分)之 队列
    C++学习(三十二)(C语言部分)之 栈
  • 原文地址:https://www.cnblogs.com/cmranger/p/4764947.html
Copyright © 2011-2022 走看看