1. 程式人生 > >The Coding World

The Coding World

實現程式碼例項:

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