Okay i've fixed your code:
ptr.hpp
#ifndef _PTR_#define _PTR_#include <cstdlib>template<class T>struct Counter { T* ptr; int count; Counter(const T* p, const int c = 1) : count(c), ptr(const_cast< T* >(p)) {}};template<class T> class Ptr {public: Ptr(const T* p = NULL) : counter(NULL) { if(p != NULL) { counter = new Counter<T>(p); } } Ptr(const Ptr<T>& r) { setPtr(r.counter); } ~Ptr() { release(); } int getCount() const { if(counter == NULL) { return 0; } else { return counter->count; } } void release() { if(counter != NULL) { (counter->count)--; if(counter->count == 0) { delete counter->ptr; delete counter; } counter = NULL; } } const Counter<T>* getCounter() const { return counter; } Counter<T>* getCounter() { return counter; } void setPtr(Counter<T>* c) { counter = c; if(c != NULL) { c->count++; } } const T& operator*() const { if(counter != NULL) { return *(reinterpret_cast<const T*>(counter->ptr)); } else { return *(reinterpret_cast<const T*>(NULL)); } } T& operator*() { if(counter != NULL) { return *(reinterpret_cast<T*>(counter->ptr)); } else { return *(reinterpret_cast<T*>(NULL)); } } const T* operator->() const { return reinterpret_cast<const T*>(counter->ptr); } T* operator->() const { return reinterpret_cast<T*>(counter->ptr); } const bool operator==(const T* rhs) const { if(counter == NULL) { return rhs == NULL; } else { return counter->ptr == reinterpret_cast<void*>(rhs); } } template<class cType> operator cType* () { if(counter == NULL) { return NULL; } else { return reinterpret_cast<cType*>(counter->ptr); } } template<class cType> operator const cType* () const { if(counter == NULL) { return NULL; } else { return reinterpret_cast<const cType*>(counter->ptr); } } const bool operator!=(const T* rhs) const { return !(*this == rhs); } template<class convertType> bool operator==(const Ptr<convertType> rhs) const { if(counter == NULL) { return rhs.getCounter() == NULL || rhs.getCounter()->ptr == NULL; } else { return rhs.getCounter() != NULL && counter->ptr == rhs.getCounter()->ptr; } } template<class convertType> bool operator!=(const Ptr<convertType> rhs) const { return !(*this == rhs); } Ptr& operator=(const Ptr<T>& rhs) { if(this != &rhs) { release(); setPtr(rhs.getCounter()); } return *this; } template<class convertType> Ptr& operator=(const Ptr<convertType>& rhs) { if(reinterpret_cast<void*>(this) != reinterpret_cast<void*>(&rhs)) { release(); setPtr(rhs.getCounter()); } return *this; } Ptr& operator=(const T* rhs) { release(); if(rhs != NULL) { counter = new Counter<T>(rhs); } return *this; } private: Counter<T>* counter;};template<> class Ptr<void> {public: Ptr(void* p = NULL) : counter(NULL) { if(p != NULL) { counter = new Counter<void>(p); } } Ptr(const Ptr<void>& r) { setPtr(r.counter); } ~Ptr() { release(); } int getCount() const { if(counter == NULL) { return 0; } else { return counter->count; } } void release() { if(counter != NULL) { (counter->count)--; if(counter->count == 0) { delete counter->ptr; delete counter; } counter = NULL; } } const Counter<void>* getCounter() const { return counter; } Counter<void>* getCounter() { return counter; } void setPtr(Counter<void>* c) { counter = c; if(c != NULL) { c->count++; } } template<class cType> operator const cType* () const { if(counter == NULL) { return NULL; } else { return reinterpret_cast<const cType*>(counter->ptr); } } template<class cType> operator cType* () { if(counter == NULL) { return NULL; } else { return reinterpret_cast<cType*>(counter->ptr);; } } const bool operator==(const void* rhs) const { if(counter == NULL) { return rhs == NULL; } else { return counter->ptr == rhs; } } const bool operator!=(const void* rhs) const { return !(*this == rhs); } template<class convertType> bool operator==(const Ptr<convertType> rhs) const { if(counter == NULL) { return rhs.getCounter() == NULL || rhs.getCounter()->ptr == NULL; } else { return rhs.getCounter() != NULL && counter->ptr == rhs.getCounter()->ptr; } } template<class convertType> bool operator!=(const Ptr<convertType> rhs) const { return !(*this == rhs); } Ptr& operator=(const Ptr<void>& rhs) { if(this != &rhs) { release(); setPtr(const_cast< Counter<void>* >(rhs.getCounter())); } return *this; } template<class convertType> Ptr& operator=(const Ptr<convertType>& rhs) { if(reinterpret_cast<void*>(this) != reinterpret_cast<void*>(&rhs)) { release(); setPtr(rhs.getCounter()); } return *this; } Ptr& operator=(const void* rhs) { release(); if(rhs != NULL) { counter = new Counter<void>(rhs); } return *this; }private: Counter<void>* counter;};template<class T, class U> Ptr<T> cast(Ptr<U>& c) { Ptr<T> rVal; rVal.setPtr(c.getCounter()); return rVal;}#endif
main.cpp
#include "ptr.h"#include <cstdlib>#include <iostream>int main() { Ptr<void> x(new int(55)); int* y = x; std::cout << *y << std::endl; return EXIT_SUCCESS;}
I just wonted to mentioned a thew things also, in Counter you don't need to use void pointer your already using templates you can use the parameter. Also if you declare a method as constant one you stating your not modifing the state of the object but your returning non constant reference/pointers of members which will modifiy the state outside.
what you normally do is provide overloaded constant and non constant versions of a method like so:
template<class cType> operator const cType*() const { return reinterpret_cast<const cType*>(ptr);}template<class cType> operator cType*() { return reinterpret_cast<cType*>(ptr);}
Also if your using C++ you should try to avoid using C style casts at all costs, use the 4 c++ cast operators like i've done in the above.
[edited by - snk_kid on June 2, 2004 3:55:07 PM]