智能指针

#include "stdafx.h"

#ifndef WIN32
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
typedef pthread_mutex_t     vmutex_t;
#else
#include <windows.h>
typedef CRITICAL_SECTION     vmutex_t;
#endif

 

///////////////////////////////////////////////////////////
class Mutex
{
public:
 Mutex(void);
 virtual ~Mutex(void);

public:
 virtual void    lock();

    virtual void    unlock();

    vmutex_t    *   getId() const;


protected:
    mutable vmutex_t    myId;
};

 


Mutex::Mutex(void)
{
#ifndef WIN32
 pthread_mutex_init(&myId, NULL);
#else
 InitializeCriticalSection(&myId);
#endif
}

Mutex::~Mutex(void)
{
#ifndef WIN32
 pthread_mutex_destroy(&myId);
#else
 DeleteCriticalSection(&myId);
#endif
 
}


void Mutex::lock()
{
#ifndef WIN32
 pthread_mutex_lock(&myId);
#else
 EnterCriticalSection(&myId);
#endif
}


void Mutex::unlock()
{
#ifndef WIN32
 pthread_mutex_unlock(&myId);
#else
 LeaveCriticalSection(&myId);
#endif
}


vmutex_t * Mutex::getId() const
{
    return ( &myId );
}

///////////////////////////////////////////
#ifndef INLINE_
#define INLINE_ inline
#endif

#define VLOCK() mutex.lock()
#define VUNLOCK() mutex.unlock()
#define INC(x) ++x
#define DEC(x) --x
#define DEC_AND_CMP(x,r) --x,r = (x == 0)
#define EXCHANGE(ptr,val) void* tmp; tmp = *ptr,*ptr = val, val = tmp

 


class CountSemaphore
{
public:
 /// constructor
    INLINE_ explicit CountSemaphore(int value=0)
    :mutex(),count(value)
    {}

 /** compares the current value in the reference count to
  * value.  returns true if equal.
  * @param value   integer to compare against.
  */
    INLINE_ bool compare(int value)
    {
        bool retVal = false;
        VLOCK();
        if (value == count) retVal = true;
        VUNLOCK();
        return retVal;
    }

 /** increment the reference count by one.  This operation is atomic.
  */
    INLINE_ void increment()
    {
        VLOCK();
        INC(count);
        VUNLOCK();
    }

 /** decrement the reference count by one.  This operation is
  * atomic.  If the reference count now equals 0, decrement
  * returns true.
  */
    INLINE_ bool decrement()
    {
        bool retVal;
        VLOCK();
        DEC_AND_CMP(count, retVal);
        VUNLOCK();
        return retVal;
    }

 


    INLINE_ void exchange(void** ptr, void** val)
    {
        VLOCK();
  EXCHANGE(ptr, *val);
        VUNLOCK();
    }

 INLINE_ int getCount() const
 {
  return count;
 }

 bool operator==(int value) const
 {
            return (value == count);
 }

    void lock()
    {
        VLOCK();
    }

    void unlock()
    {
        VUNLOCK();
    }


private:
 /// suppress copying
    CountSemaphore(const CountSemaphore* pvalue);
 /// suppress copying
    const CountSemaphore& operator=(const CountSemaphore* pvalue);
 /// suppress comparison
    bool operator==(const CountSemaphore* pvalue);


    Mutex mutex;

   volatile int count; // why is this volatile ?
};


CountSemaphore::CountSemaphore(const CountSemaphore* pvalue)
:mutex(),count(0)
{
 count = pvalue->getCount();
}

const CountSemaphore& CountSemaphore::operator=(const CountSemaphore* pvalue)
{
 int icount = pvalue->getCount();
 VLOCK();
 count = icount;
 VUNLOCK();

 return *this;
}

 

bool CountSemaphore::operator==(const CountSemaphore* pvalue)
{
 int icount = pvalue->getCount();
 return count == icount;
}

/////////////////////////////////////////////////////////


template < class T >
class Sptr
{
// we need to work around Visual C++'s limitations. this
// is needed so that we can grab these bits directly

private:

        mutable  T* ptr;
        mutable CountSemaphore* count;

public:

        /// increment the reference count.
        void increment()
        {
            if (ptr)
            {
                if (!count)
                {
                    count = new CountSemaphore();
                }

                count->increment();
            }
        }

        /// decrement the reference count
        void decrement()
        {
            if (ptr && count)
            {

                if(count->decrement())
                {
                    delete ptr;
                    delete count;
                }
            }
            ptr = 0;
            count = 0;
        }


        /** conversion operator converts pointers of this const class
         * to class const Sptr< T2 >., where T2 is a different base
         * class.  This is most often used when attempting to call a
         * const method of the base class through a derived class
         * pointer.  This is a workaround for SUNPRO .
         */

 

        template < class T2 >
        operator const Sptr<T2 > () const
        {
            return Sptr < T2 > (ptr, count);
        }

 

 

        /// default constructor.  points to NULL.
        Sptr() : ptr(0), count(0)
        {}
        ;

 


        /** constructor used most often as the constructor from a
         * plain pointer.  Do not use this to convert a single pointer
         * to a smart pointer multiple times -- this will result in an
         * error (see class introduction for details).
         */

 

        Sptr(T* original, CountSemaphore* myCount = 0)
        : ptr(original), count(myCount)
        {
            if (ptr)
            {
                increment();
            }
        };


        /** copy constructor
         */
        Sptr(const Sptr& x)
        : ptr(x.ptr), count(x.count)
        {
            increment();
        };

        /// destructor
        ~Sptr()
        {
            {

                decrement();

            }
        }

 

        /// dereference operator
        T& operator*() const
        {
            return *ptr;
        }

        /// ! operator .  Returns true if ptr == 0, false otherwise.
        int operator!() const
        {
            if (ptr)
            {
                return (ptr == 0);
            }
            else
                return true;
        }

 

       /// pointer operator.
        T* operator->() const
        {
            return ptr;
        }

        template < class T2 > Sptr& dynamicCast(const Sptr < T2 > & x)
        {
            if (ptr == x.getPtr()) return *this;

            decrement();
            if(T* p = dynamic_cast < T* > (x.getPtr()))
            {
                count = x.getCount();
                ptr = p;
                increment();
            }

            return *this;
        }

 

        /** assignment operator -- this is most often used to assign
         * from a smart pointer to a derived type to a smart pointer
         * of the base type.
         */
        template < class T2 >
        Sptr& operator=(const Sptr < T2 > & x)
        {
            if (ptr == x.getPtr()) return * this;

            decrement();
            ptr = x.getPtr();
            count = x.getCount();
            increment();

            return *this;
        }

 

       /** assignment operator from plain pointer.  Do not use this
         * to convert a single pointer to a smart pointer multiple
         * times -- this will result in an error (see class
         * introduction for details).
         */
        Sptr& operator=(T* original)
        {
            if (ptr == original) return * this;

            decrement();

            ptr = original;
            increment();

            return *this;
        };

 

       /// assignment operator
        Sptr& operator=(const Sptr& x)
        {
            if (ptr == x.ptr) return * this;

            decrement();
            ptr = x.ptr;
            count = x.count;
            increment();

            return *this;
        }

 

        /// compare whether a pointer and a smart pointer point to different things
        friend bool operator!=(const void* y, const Sptr& x)
        {
            if (x.ptr != y)
                return true;
            else
                return false;
        }

        /// compare whether a smart pointer and a pointer point to different things
        friend bool operator!=(const Sptr& x, const void* y)
        {
            return (y != x);
        }

 

       /// compare whether a pointer and a smart pointer point to the same thing
        friend bool operator==(const void* y, const Sptr& x)
        {
            if (x.ptr == y)
                return true;
            else
                return false;
        }

        /// compare whether a smart pointer and a pointer point to the same thing
        friend bool operator==(const Sptr& x, const void* y)
        {
            return (y == x);
        }

 

       /// compare whether two smart pointers point to the same thing
        bool operator==(const Sptr& x) const
        {
            if (x.ptr == ptr)
                return true;
            else
                return false;
        }

        /// compare whether two smart pointers point to the same thing
        bool operator!=(const Sptr& x) const
        {
            return !(operator==(x));
        }

 

 

        /**
           this interface is here because it may sometimes be
           necessary.  DO NOT USE unless you must use it.
           get the value of the reference count of the smart pointer.
        */
        CountSemaphore* getCount() const
        {
            return count;
        }

 

       /**
           this interface is here because it may sometimes be
           necessary.  DO NOT USE unless you must use it.
           get the pointer to which the smart pointer points.
        */
        T* getPtr() const
        {
            return ptr;
        }

};


/////////////////////////////////////////////////////////////

struct stu
{
 int a;
 int b;
};

struct stuc
{
 int a;
 int b;
};

 


int _tmain(int argc, _TCHAR* argv[])
{
 Sptr<stu> pStu = new stu;

 Sptr<stu> pStuc = pStu;

 pStu->a = 10;
 pStu->b = 5;

 
 return 0;
}

你可能感兴趣的:(智能指针)