It is currently Thu Sep 20, 2018 2:54 pm




Post new topic Reply to topic  [ 1 post ] 
 free smart pointer wrapper 
Author Message
Site Admin

Joined: Wed Jun 27, 2007 9:33 am
Posts: 227
Post free smart pointer wrapper
hey, though I might release a smart pointer wrapper I made, that I use in my game.

pretty flexible, and nearly no cpu overhead and I never have to worry about dangling pointers.

it's a little different from other smart pointers I've seen.

example of it's use:
Code:

ptrWrap
<CCar> redCar=new CCar;
ptrWrap<CCar> randomCar=redCar;

redCar->Drive();

//can be mixed with normal pointers.
CCar *testCar=redCar;
testCar->Remove();
testCar=0;

if (randomCar)
{
   //never here, car was deleted
   randomCar->OpenDoor(); 
}

 



Code:
#ifndef SMART_PTR_H_INCLUDED
#define SMART_PTR_H_INCLUDED



//A little Pointer wrapper, made by me
//it uses reference counting but lets you delete (in a sense) objects anytime you like
//without creating dangling pointers, (works like weak pointers only based on the object)

//Copyright (c) Luke Hoschke
//Permission to use under the zlib/libpng License


#ifdef SAFETY_CHECKS
    #define POINTER_WRAPPER_DEREFERENCE_CHECK
    #define POINTER_WRAPPER_DELETE_CHECK
#else
    #warning pointer wrapper safety not on
#endif

#ifdef POINTER_WRAPPER_DELETE_CHECK
    #include <stdio.h>
#endif

#ifdef POINTER_WRAPPER_DELETE_ERROR
    #include <assert.h>
#endif

class CReferenceCounted
{
public:
    CReferenceCounted():ref_count(0), removed(false){}
    virtual ~CReferenceCounted(){}
    virtual void Remove(){removed=true;}

    unsigned short ref_count;
    bool removed;
};

template <class T> //class T must be derived from CReferenceCounted
class ptrWrap
{
public:
    CReferenceCounted *ptr;

    ptrWrap() : ptr(0) {}
    ptrWrap(ptrWrap<T> &p) : ptr(p.ptr) { if (ptr!=0) ref(); }
    ptrWrap(const ptrWrap<T> &p) : ptr(p.ptr) { if (ptr!=0) ref(); }

    ptrWrap(*p)
    {
        ptr=p; //an error here may mean class T is not derived from CReferenceCounted
        if (ptr!=0) ref();
    }

    ~ptrWrap()
    {
        if (ptr!=0) unref();
    }

    T& operator*()
    {
        #ifdef POINTER_WRAPPER_DEREFERENCE_CHECK
            check(); //Not needed, just an extra check for bad pointers
        #endif
        return *ptr;
    }
    T* operator->()
    {
        #ifdef POINTER_WRAPPER_DEREFERENCE_CHECK
            check(); //Not needed, just an extra check for bad pointers
        #endif
        return (T*)ptr;
    }

    //--- int/bool ---//

    intptr_t &operator=(intptr_t &p)
    {
        if (ptr!=0) unref();
        ptr=(CReferenceCounted*)p;
        if (ptr!=0) ref();
        return p;
    }

    operator intptr_t()
    {
        check();
        return (intptr_t)ptr;
    }

    operator bool()
    {
        check();
        return (ptr);
    }

    //--- ptrWrap<T> ---//


    bool operator!=(ptrWrap<T> &p)
    {check();p.check(); return (ptr!=p.ptr);}

    bool operator==(ptrWrap<T> &p)
    {check();p.check(); return (ptr==p.ptr);}

    ptrWrap<T> &operator=(ptrWrap<T> &p)
    {
        p.check();
        if (ptr!=0) unref();
        ptr = p.ptr;
        if (ptr!=0) ref();
        return p;
    }

    //--- T* ---//

    T *operator=(*p)
    {
        if (ptr==p) return p;

        if (ptr!=0) unref();
        ptr=p; //an error here may mean class T is not derived from CReferenceCounted
        if (ptr!=0) ref();
        return p;
    }

    operator T *()
    {
        check();
        return (T*)ptr;
    }

    //--- Referencing ---//

    void ref()
    {
        ptr->ref_count++;
    }
    void unref()
    {
        ptr->ref_count--;
        if (ptr->ref_count==0)
        {
            #ifdef POINTER_WRAPPER_DELETE_CHECK
                if (!ptr->removed) printf("ptrWrap: deleting an object not set to be removed \n");
            #endif
            #ifdef POINTER_WRAPPER_DELETE_ERROR
                assert(ptr->removed); //deleting an object not set to be removed
            #endif
            delete ptr;
        }
    }

    void check()
    {
        if (ptr==0) return;
        if (ptr->removed==true)
            {unref(); ptr=0;}
    }




};



#endif // SMART_PTR_H_INCLUDED
 


let me know what you think, if you find any bugs, etc.


Sun Jul 13, 2008 5:11 pm
Profile
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 1 post ] 


Who is online

Users browsing this forum: No registered users and 7 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © phpBB Group.
Designed by Vjacheslav Trushkin for Free Forums/DivisionCore.