00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
#include "BasicException.h"
00026
00027
#ifndef BASICSMARTPOINTER_H
00028
#define BASICSMARTPOINTER_H
00029
00030
#include "BasicCounter.h"
00031
00032
#include <stdlib.h>
00033
00034
00035
class BasicException;
00036
00037
typedef enum {SP_NEW, SP_ARRAY, SP_MALLOC} sp_alloc_t;
00038
00066
template <
class T, sp_alloc_t alloc_t = SP_NEW>
00067
class BasicSmartPointer {
00069
BasicCounter *refCounter;
00070
00072 T *ptr;
00073
00074
public:
00079 BasicSmartPointer() : refCounter(0), ptr(0) {}
00080
00087 BasicSmartPointer(
const BasicSmartPointer<T, alloc_t> &smartPtr) :
00088 refCounter(0), ptr(0) {
00089 *
this = smartPtr;
00090 }
00091
00104 BasicSmartPointer(T *ptr) : refCounter(0), ptr(0) {
00105
if (ptr) {
00106 refCounter =
new BasicCounter(1);
00107 this->ptr = ptr;
00108 }
00109 }
00110
00116 ~BasicSmartPointer() {release();}
00117
00126
const bool operator==(
const BasicSmartPointer<T, alloc_t> &smartPtr) {
00127
return ptr == smartPtr.ptr;
00128 }
00129
00138
const bool operator==(
const T *ptr) {
00139
return this->ptr == ptr;
00140 }
00141
00150 BasicSmartPointer<T, alloc_t> &
00151 operator=(
const BasicSmartPointer<T, alloc_t> &smartPtr) {
00152
if (*
this == smartPtr)
return *
this;
00153
00154 release();
00155
00156 refCounter = smartPtr.refCounter;
00157
if (refCounter) refCounter->inc();
00158 ptr = smartPtr.ptr;
00159
00160
return *
this;
00161 }
00162
00169 T *operator->()
const {checkPtr();
return get();}
00170
00177 T &operator*()
const {checkPtr();
return *get();}
00178
00186 T &operator[](
const long x)
const {checkPtr();
return get()[x];}
00187
00193 T *get()
const {
return ptr;}
00194
00196
bool operator!()
const {
return ptr == 0;}
00197
00203
void release() {
00204
if (refCounter && !refCounter->dec()) {
00205
delete refCounter;
00206
switch (alloc_t) {
00207
case SP_NEW:
delete ptr;
break;
00208
case SP_ARRAY:
delete [] ptr;
break;
00209
case SP_MALLOC: free(ptr);
break;
00210 }
00211 }
00212
00213 refCounter = 0;
00214 ptr = 0;
00215 }
00216
00227 T *adopt() {
00228
if (refCounter && refCounter->getCount() > 1)
00229
throw BasicException(std::string(
"BasicSmartPointer: Cannot adopt a") +
00230
"pointer with multiple references!");
00231
00232
if (refCounter) {
00233
delete refCounter;
00234 refCounter = 0;
00235 }
00236 T *tmp = ptr;
00237 ptr = 0;
00238
00239
return tmp;
00240 }
00241
00250
long getRefCount()
const {
return refCounter ? refCounter->getCount() : 0;}
00251
00257
bool isNull()
const {
return get() == 0;}
00258
00259
protected:
00260
void checkPtr()
const {
00261
if (!ptr)
00262
throw
00263
BasicException(
"BasicSmartPointer: Can't dereference a NULL pointer!");
00264 }
00265 };
00266
#endif