⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shared_ptr.h

📁 用于使用moden进行传真的源代码
💻 H
字号:
/* Copyright (C) 2004 Chris VineThis program is distributed under the General Public Licence, version 2.For particulars of this and relevant disclaimers see the fileCOPYING distributed with the source files.*/#ifndef SHARED_PTR_H#define SHARED_PTR_H#include <glibmm/thread.h>template <class T> class Shared_ptr {  struct {    unsigned int* ref_count_p;    T* obj_p;  } ref_items;  void unreference(void) {    --*ref_items.ref_count_p;    if (*ref_items.ref_count_p == 0) {      delete ref_items.obj_p;  // if this is NULL it is still safe to apply delete to it      delete ref_items.ref_count_p;    }  }  void reference(void) {    ++*ref_items.ref_count_p;  }public:  // constructor of first Shared_ptr holding the referenced object  explicit Shared_ptr(T* ptr = 0) {    ref_items.ref_count_p = new unsigned int(1);    ref_items.obj_p = ptr;  }  // copy constructors  Shared_ptr(const Shared_ptr& sh_ptr) throw() {    ref_items = sh_ptr.ref_items;    reference();  }  template <class U> friend class Shared_ptr;  template <class U> Shared_ptr(const Shared_ptr<U>& sh_ptr) throw() {    // because we are allowing an implicit cast from derived to    // base class referenced object, we need to assign from each    // member of sh_ptr.ref_items separately    ref_items.ref_count_p = sh_ptr.ref_items.ref_count_p;    ref_items.obj_p = sh_ptr.ref_items.obj_p;    reference();  }  // copy assignment  Shared_ptr& operator=(const Shared_ptr& sh_ptr) throw() {    // check whether we are already referencing this object -    // if so make this a null op.  This will also deal with    // self-assignment    if (ref_items.obj_p != sh_ptr.ref_items.obj_p) {      // first unreference any object referenced by this shared pointer      unreference();      // now inherit the ref_items structure from the assigning      // shared pointer and reference the object it references      ref_items = sh_ptr.ref_items;      reference();    }    return *this;  }  template <class U> Shared_ptr& operator=(const Shared_ptr<U>& sh_ptr) throw() {    return operator=(Shared_ptr(sh_ptr));  }  T* get(void) const throw() {return ref_items.obj_p;}  T& operator*(void) const throw() {return *ref_items.obj_p;}  T* operator->(void) const throw() {return ref_items.obj_p;}  unsigned int get_refcount(void) const throw() {return *ref_items.ref_count_p;}  // destructor  ~Shared_ptr(void) throw() {unreference();}};/*  Class Shared_lock_ptr is a version of the shared pointer class which  includes mutex locking so that it can be accessed in multiple  threads. Note that only the reference count is protected by a mutex,  so this is thread safe in the sense in which a raw pointer is thread  safe.  A shared pointer accessed in one thread referencing a  particular object is thread safe as against another shared pointer  accessing the same object in a different thread.  It is thus  suitable for use in different Std C++ containers which exist in  different threads but which contain shared objects by reference.  But:  1.  If the referenced object is to be modified in one thread and      read or modified in another thread an appropriate mutex for the      referenced object is required (unless that referenced object      does its own locking).  2.  If the same instance of shared pointer is to be modified in one      thread (by assigning to the pointer so that it references a      different object), and copied (assigned from or used as the      argument of a copy constructor) or modified in another thread, a      mutex for that instance of shared pointer is required.  3.  Objects referenced by shared pointers which are objects for      which POSIX provides no guarantees (in the main, those which are      not built-in types), such as strings and similar containers, may      not support concurrent reads in different threads.  That depends      on the library implementation concerned.  If that is the case, a      mutex for the referenced object will also be required when      reading any given instance of such an object in more than one      thread by dereferencing any shared pointers referencing it (and      indeed, when not using shared pointers at all).*/template <class T> class Shared_lock_ptr {  struct Ref_items {    Glib::Mutex* mutex_p;    unsigned int* ref_count_p;    T* obj_p;  } ref_items;  void unreference(void) {    // the mutex in ref_items will have been locked before we got here    // so we do not need to lock it in this method.  The call to this method    // which results in the deletion of the referenced object (that is, which    // cause the reference count to reach 0) will have been made in the    // destructor of this shared pointer instance so we need to unlock() the    // mutex and then delete it    --*ref_items.ref_count_p;    if (*ref_items.ref_count_p == 0) {      delete ref_items.obj_p;  // if this is NULL it is still safe to apply delete to it      delete ref_items.ref_count_p;      // the referenced object has now been destroyed      // it is safe to unlock the mutex here and then      // to delete the mutex - there can be no further call      // to this method with respect to that object      ref_items.mutex_p->unlock();      delete ref_items.mutex_p;      // set ref_items.mutex_p to NULL so that the destructor and operator=()      // know not to try and unlock the mutex where we called ref_itemserence() in the      // destructor or operator=()      ref_items.mutex_p = 0;    }  }    void reference(void) {    ++*ref_items.ref_count_p;  }public:  // constructor of first Shared_lock_ptr holding the referenced object  explicit Shared_lock_ptr(T* ptr = 0) {    ref_items.mutex_p = new Glib::Mutex;    // make this constructor exception safe    try {      ref_items.ref_count_p = new unsigned int(1);    }    catch (...) {      delete ref_items.mutex_p;      throw;    }    ref_items.obj_p = ptr;  }  // copy constructors  Shared_lock_ptr(const Shared_lock_ptr& sh_ptr) throw() {    ref_items = sh_ptr.ref_items;    Glib::Mutex::Lock lock(*ref_items.mutex_p);    reference();  }  template <class U> friend class Shared_lock_ptr;  template <class U> Shared_lock_ptr(const Shared_lock_ptr<U>& sh_ptr) throw() {    // because we are allowing an implicit cast from derived to    // base class referenced object, we need to assign from each    // member of sh_ptr.ref_items separately    ref_items.mutex_p = sh_ptr.ref_items.mutex_p;    ref_items.obj_p = sh_ptr.ref_items.obj_p;    ref_items.ref_count_p = sh_ptr.ref_items.ref_count_p;    Glib::Mutex::Lock lock(*ref_items.mutex_p);    reference();  }  // copy assignment  Shared_lock_ptr& operator=(const Shared_lock_ptr& sh_ptr) throw() {    // check whether we are already referencing this object -    // if so make this a null op.  This will also deal with    // self-assignment    if (ref_items.obj_p != sh_ptr.ref_items.obj_p) {      // first unreference any object referenced by this shared pointer      ref_items.mutex_p->lock();      unreference();      if (ref_items.mutex_p) ref_items.mutex_p->unlock();            // now inherit the ref_items structure from the assigning      // shared pointer and reference the object it references      ref_items = sh_ptr.ref_items;      Glib::Mutex::Lock lock(*ref_items.mutex_p);      reference();    }    return *this;  }  template <class U> Shared_lock_ptr& operator=(const Shared_lock_ptr<U>& sh_ptr) throw() {    return operator=(Shared_lock_ptr(sh_ptr));  }    T* get(void) const throw() {return ref_items.obj_p;}  T& operator*(void) const throw() {return *ref_items.obj_p;}  T* operator->(void) const throw() {return ref_items.obj_p;}  unsigned int get_refcount(void) const throw() {    Glib::Mutex::Lock lock(*ref_items.mutex_p);    return *ref_items.ref_count_p;  }  // destructor  ~Shared_lock_ptr(void) throw() {    ref_items.mutex_p->lock();    unreference();    // if unreference() has deleted the referenced object because    // this is the last shared pointer referencing it, we do not    // want to unlock here as the mutex will have been destroyed    // also    if (ref_items.mutex_p) ref_items.mutex_p->unlock();  }};#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -