The Coding World
阿新 • • 發佈:2019-02-08
實現程式碼例項:
SmartPtr.h
#include "Mutex.h" #include <iostream> class CRef //as smarty pointer counter, { public: CRef():_ref(0){} virtual ~CRef(){} CRef(const CRef&):_ref(0) {} CRef& operator=(const CRef&) { return *this; } virtual void IncRef() { mutex.Lock(); ++_ref; mutex.UnLock(); } virtual void DecRef() { mutex.Lock(); --_ref; mutex.UnLock(); if(_ref == 0) { delete this; } } virtual int getRef() { mutex.Lock(); return _ref; mutex.UnLock(); } private: int _ref; Mutex mutex; }; template <typename T> class SmartPtr { public: SmartPtr(T* ptr):m_ptr(ptr) { if(m_ptr) { m_ptr->IncRef(); } std::cout << "SmatePtr:: SmatePtr()invoke\n"; } SmartPtr():m_ptr(new T()) { if(m_ptr) { m_ptr->IncRef(); } std::cout << "SmatePtr:: SmatePtr()invoke\n"; } virtual ~SmartPtr() { if(m_ptr) { m_ptr->DecRef(); } std::cout << "SmatePtr:: ~SmatePtr()invoke\n"; } SmartPtr(const SmartPtr& sptr) { this->m_ptr = sptr.m_ptr; if(this->m_ptr) { this->m_ptr->IncRef(); } std::cout << "SmatePtr:: SmatePtr()invoke\n"; } SmartPtr& operator=(const T& p) { if(this->m_ptr != p) { if(p) { p->IncRef(); } T* ptr = this->m_ptr; this->m_ptr = p; if(ptr) { ptr->DecRef(); } } return *this; } SmartPtr& operator=(const SmartPtr& sptr) { if(this->m_ptr != sptr.m_ptr) { if(sptr.m_ptr) { sptr.m_ptr->IncRef(); } T* ptr = this->m_ptr; this->m_ptr = sptr.m_ptr; if(ptr) { ptr->DecRef(); } } return *this; } T* get()const { return m_ptr;} T* operator->()const { if(m_ptr) { return m_ptr; } } T& operator*() const { if(m_ptr) { return *(m_ptr); } } operator bool() const { return m_ptr?true:false;} private: T* m_ptr; }; template <typename T, class U> inline bool operator==(const SmartPtr<T>& lhs, const SmartPtr<U>& rhs) { T* l = lhs.get(); U* r = rhs.get(); if(l && r) { return *l == *r; } return !l && !r; } template <typename T, class U> inline bool operator!=(const SmartPtr<T>& lhs, const SmartPtr<U>& rhs) { return !operator==(lhs, rhs); }
測試程式碼:
TestSmart.cpp
#include "SmartPtr.h" #include <iostream> class Test :public CRef { public: Test():data(0) { std::cout << "test::test invoke\n"; } Test(int a):data(a) { std::cout << "test::test invoke\n"; } virtual ~Test() { std::cout << "test::~test() invoked\n"; } private: int data; }; int main(int argc, char *argv[]) { // Test *t = new Test(10); // SmartPtr<Test> p(t); // SmartPtr<Test> p2(p); // SmartPtr<Test> p3 = p2; SmartPtr<Test> t; return 0; }
Mutex.h
#include <cstdlib> #include <pthread.h> #include <errno.h> #include <unistd.h> #include <cstdio> #include <string.h> class Mutex { public: Mutex(); virtual ~Mutex(); void Lock(); void UnLock(); private: friend class CondVar; pthread_mutex_t m_mutex; Mutex(const Mutex&); void operator=(const Mutex&); }; class CondVar { public: explicit CondVar(Mutex* mu); virtual ~CondVar(); void Wait(); void Signal(); void SignalAll(); private: pthread_cond_t m_cond; Mutex *m_mu; }; class CASLock { public: CASLock(void* lock); virtual ~CASLock(); void Lock(); void UnLock(); bool TryLock(); private: void* m_lock; }; static void MutexErr(const char* err, int res) { if(res != 0) { fprintf(stderr, "pthread %s: %s\n", err, strerror(res)); return; } } Mutex::Mutex() { MutexErr("init mutex", pthread_mutex_init(&m_mutex, NULL)); } Mutex::~Mutex() { MutexErr("destroy mutex", pthread_mutex_destroy(&m_mutex)); } void Mutex::Lock() { MutexErr("lock mutex", pthread_mutex_lock(&m_mutex)); } void Mutex::UnLock() { MutexErr("unlock mutex", pthread_mutex_unlock(&m_mutex)); } CondVar::CondVar(Mutex* mu):m_mu(mu) { MutexErr("init cond", pthread_cond_init(&m_cond, NULL)); } CondVar::~CondVar() { MutexErr("destroy cond", pthread_cond_destroy(&m_cond)); } void CondVar::Wait() { MutexErr("wait cond", pthread_cond_wait(&m_cond, &m_mu->m_mutex)); } void CondVar::Signal() { MutexErr("signal cond", pthread_cond_signal(&m_cond)); } void CondVar::SignalAll() { MutexErr("broadcast cond", pthread_cond_broadcast(&m_cond)); } CASLock::CASLock(void* lock):m_lock(lock){} CASLock::~CASLock(){} void CASLock::Lock() { while(!__sync_bool_compare_and_swap((int*)m_lock, 0, 1)) { sched_yield(); } } void CASLock::UnLock() { *((int*)m_lock) = 0; } bool CASLock::TryLock() { if(__sync_bool_compare_and_swap((int*)m_lock, 0, 1)) return 0; else return -1; }
編譯:
g++ -o test SmartPtr.h TestSmart.cpp Mutex.h