#ifndef POINTER #define POINTER #include template class Pointer{ public: class InvalidPointerSize : public std::exception{}; class PointerOutOfRange : public std::exception{}; Pointer(unsigned int N=1) throw(InvalidPointerSize); Pointer(const Pointer & pointer); Pointer(const T & t); Pointer & operator = (const Pointer & pointer); ~Pointer(); T * operator->(void); T * operator [](unsigned int index) throw(PointerOutOfRange); T & operator *(void) const; private: struct Data{ unsigned int N; T * adress; unsigned int nbRef; }; void free() { if((data->nbRef)==1) { (data->N==1)?delete data->adress:delete[] data->adress; delete data; } else data->nbRef--; } void copy(Pointer::Data * data) { data->nbRef++; this->data = data; } Data * data; }; template Pointer::Pointer(unsigned int N) throw(InvalidPointerSize) :data(new Data()) { if(N==0) throw InvalidPointerSize(); if(N==1) data->adress = new T(); else data->adress = new T[N]; data->N = N; data->nbRef=1; } template Pointer::Pointer(const T & t) :data(new Data()) { data->adress = new T(t); data->N = 1; data->nbRef=1; } template Pointer::Pointer(const Pointer & pointer){ copy(pointer.data); } template Pointer & Pointer::operator =(const Pointer & pointer) { free(); copy(pointer.data); return (*this); } template Pointer::~Pointer(){ free(); } template T * Pointer::operator->(void){ return data->adress; } template T * Pointer::operator [](unsigned int index) throw(PointerOutOfRange){ if(index>(data->N-1)) throw PointerOutOfRange(); return &data->adress[index]; } template T & Pointer::operator *(void) const{ return (*data->adress); } #endif