怎么做透明的网站图片,岳阳君山,网站后台别人制作,大连企业模板建站1.什么是RAII#xff1f;
RAII#xff08;Resource Acquisition Is Initialization#xff09;机制是Bjarne Stroustrup首先提出的#xff0c;也称直译为“资源获取就是初始化”#xff0c;是C语言的一种管理资源、避免泄漏的机制。 C标准保证任何情况下#xff0c;已构…1.什么是RAII
RAIIResource Acquisition Is Initialization机制是Bjarne Stroustrup首先提出的也称直译为“资源获取就是初始化”是C语言的一种管理资源、避免泄漏的机制。 C标准保证任何情况下已构造的对象最终会销毁即它的析构函数最终会被调用。 RAII 机制就是利用了C的上述特性,在需要获取使用资源RES的时候构造一个临时对象(T)在其构造T时获取资源在T生命期控制对RES的访问使之始终保持有效最后在T析构的时候释放资源。以达到安全管理资源对象避免资源泄漏的目的。
2.为什么要使用RAII
那么我们经常所说的资源是如何定义的说到资源,我们立刻能想到的就是内存啊文件句柄等等啊但只有这些吗 对于资源的概念不要想象的太狭隘在计算机系统中资源是个定义宽泛的概念所有数量有限且对系统正常运行具有一定作用的元素都是资源。比如网络套接字、互斥锁、文件句柄、内存、数据库记录等等它们属于系统资源。由于系统的资源是有限的就好比自然界的石油铁矿一样不是取之不尽用之不竭的。 所以我们在编程使用系统资源时都必须遵循一个步骤
1.申请资源 2.使用资源 3.释放资源。
第一步和第三步缺一不可因为资源必须要申请才能使用的使用完成以后必须要释放如果不释放的话就会造成资源泄漏。
3.实战应用
3.1一个简单的例子指针申请空间释放空间
void Func()
{ int *ip new int[10]; //operations //operations //operations delete[] ip;//if not free mem, memory overflow
} 使用RAII技术后
templateclass PointerType
class My_Pointer
{
public: My_Pointer(PointerType* _ptr, size_t sz) { _ptr new PointerType[sz]; m_ptr _ptr; } ~My_Pointer() { delete []m_ptr; }
protected: PointerType m_ptr;
}
3.2 scope lock (局部锁技术) 在很多时候为了实现多线程之间的数据同步我们会使用到 mutex,critical section,event,singal 等技术。但在使用过程中由于各种原因有时候我们会遇到一个问题由于忘记释放Unlock锁产生死锁现象。 采用RAII 就可以很好的解决这个问题,使用着不必担心释放锁的问题. 示例代码如下: My_scope_lock 为实现 局部锁的模板类. LockType 抽象代表具体的锁类 .如基于 mutex 实现 mutex_lock 类
templateclass LockType
class My_scope_lock
{
public: My_scope_lock(LockType _lock):m_lock(_lock) { m_lock.occupy(); } ~My_scope_lock() { m_lock.relase(); }
protected: LockType m_lock;
}
使用的时候
//global vars
int counter 0;
void routine();
mutex_lock m_mutex_lock;
void routine()
{ My_scope_lock l_lock(m_mutex_lock); counter; //others...
}
我们可以根据上面的例子类推出好多这样例子。如读写文件的时候很容易忘记关闭文件如果借用 RAII技术,就可以规避这种错误。再如对数据库的访问忘记断开数据库连接等等都可以借助RAII 技术也解决。
4.RAII模板化实现
按照上节的做法,如果你有很多个资源对象要用RAII方式管理按这个办法就要为每个类写一个RAII类。 想到这里我瞬间觉得好烦燥都是类似的代码却要一遍一遍的重复,就不能有个通用的方法让我少写点代码嘛 于是我利用C11的新特性(类型推导、右值引用、移动语义、类型萃取、function/bind、lambda表达式等等)写了一个通用化的RAII机制,满足各种类型资源的管理需求。
//
// RAII.h
//
// Library: Foundation
// Package: Core
// Module: RAII
//
// Definition of the RAII template class and friends.
//
//#include Wishbone/Foundation.h
#include type_traits
#include functionalnamespace Wishbone
{/* 元模板如果是const类型则去除const修饰符 */templatetypename Tstruct no_const{using type typename std::conditionalstd::is_constT::value, typename std::remove_constT::type, T::type;};/// RAII方式管理申请和释放资源的类/// 对象创建时,执行acquire(申请资源)动作(可以为空函数[]{})/// 对象析构时,执行release(释放资源)动作/// 禁止对象拷贝和赋值class RAII{public:typedef std::functionvoid() FunctionType;/// release: 析构时执行的函数/// acquire: 构造函数执行的函数/// default_com:_commit,默认值,可以通过commit()函数重新设置explicit RAII(FunctionType release, FunctionType acquire [] {}, bool default_com true) noexcept :_commit(default_com),_release(release){acquire();}/// 对象析构时根据_commit标志执行_release函数~RAII() noexcept{if (_commit)_release();}/// 移动构造函数 允许右值赋值RAII(RAII rv) noexcept : _commit(rv._commit),_release(rv._release){rv._commit false;};///RAII commit(bool c true) noexcept;protected:std::functionvoid() _release;private:RAII(const RAII);RAII operator(const RAII) delete;bool _commit;}; /* RAII *//// inlinsinline RAII RAII::commit(bool c true) noexcept{ _commit c; return *this; };/// 用于实体资源的RAII管理类/// T为资源类型/// acquire为申请资源动作返回资源T/// release为释放资源动作,释放资源Ttemplatetypename Tclass RAIIVar{public:typedef std::functionT() AcquireType;typedef std::functionvoid(T ) ReleaseType;///explicit RAIIVar(AcquireType acquire, ReleaseType release) noexcept :_resource(acquire()),_release(release){}/// 移动构造函数RAIIVar(RAIIVar rv) :_resource(std::move(rv._resource)),_release(std::move(rv._release)){rv._commit false;//控制右值对象析构时不再执行_release}/// 对象析构时根据_commit标志执行_release函数~RAIIVar() noexcept{if (_commit)_release(_resource);}RAIIVarT commit(bool c true) noexcept{ _commit c; return *this;};T get() noexcept{return _resource; }T operator*() noexcept{return get();}templatetypename _T Ttypename std::enable_ifstd::is_pointer_T::value, _T::type operator-() const noexcept{return _resource;}templatetypename _T Ttypename std::enable_ifstd::is_class_T::value, _T*::type operator-() const noexcept{return std::addressof(_resource);}private:bool _commit true;T _resource;ReleaseType _release;};/// 创建 RAII 对象,/// 用std::bind将M_REL,M_ACQ封装成std::functionvoid()创建RAII对象/// RES 资源类型/// M_REL 释放资源的成员函数地址/// M_ACQ 申请资源的成员函数地址templatetypename RES, typename M_REL, typename M_ACQRAII make_raii(RES res, M_REL rel, M_ACQ acq, bool default_com true) noexcept{static_assert(std::is_classRES::value, RES is not a class or struct type.);static_assert(std::is_member_function_pointerM_REL::value, M_REL is not a member function.);static_assert(std::is_member_function_pointerM_ACQ::value, M_ACQ is not a member function.);assert(nullptr ! rel nullptr ! acq);auto p_res std::addressof(const_casttypename no_constRES::type(res));return RAII(std::bind(rel, p_res), std::bind(acq, p_res), default_com);}templatetypename RES, typename M_RELRAII make_raii(RES res, M_REL rel, bool default_com true) noexcept{static_assert(std::is_classRES::value, RES is not a class or struct type.);static_assert(std::is_member_function_pointerM_REL::value, M_REL is not a member function.);assert(nullptr ! rel);auto p_res std::addressof(const_casttypename no_constRES::type(res));return RAII(std::bind(rel, p_res), [] {}, default_com);}} // namespace Wishbone