/*
1.用类来表示概念,将复杂的功能拆分成小模块,每个类只做一件事情。
2.Pointer来专门用来访问数据,Array_data类是中间层,避免了用户删除对象指针导致内存泄漏的问题,Array类是专门提供给用户操作的类(层次分明)
*/
///Array用户避免使用指针操作
template<class T>
class Array
{
friend class Pointer<T>;
public:
Array(unsigned size):
data(new Array_data<T>(sze)){}
~Array()
{
if (--data->use == 0)
{
delete data;
}
}
const T& operator[](unsigned n)const
{
return (*data)[n];
}
T& operator[](unsigned n)
{
return (*data)[n];
}
void resize(unsigned n)
{
data->resize(n);
}
void reserve(unsigned new_sz)
{
if (new_sz >= data->sz)
{
data->grow(new_sz);
}
}
Array(const Array& a):data(Array_data<T>)(a.data->sz)
{
data->copy(a.data->data, a.data->sz);
}
Array& operator=(const Array& a)
{
if (this != &a)
{
data->clone(*a.data, a.data->data);
}
return *this;
}
private:
Array(const Array&);
Array& operator=(const Array&);
Array_data<T>* data;
};
/*
* 通过引进一个额外的中间层,能够解决大部分问题,在该类中通过引用计数器的技术实现了删除不同的指针对象删除对象后原对象还存在
*/
template<class T>
class Array_data
{
friend class Array<T>;
friend class Pointer<T>;
Array_data(unsigned size = 0):
data(new T[size]), sz(size), use(1){}
~Array_data()
{
delete [] data;
}
T& operator[](unsigned n) const
{
if (n >= sz)
{
throw "Array subscript out of range";
}
return data[n];
}
T& operator[](unsigned n)
{
if (n >= sz)
{
throw "Array subscript out of range";
}
return data[n];
}
void resize(unsigned n)
{
if (n == sz)
{
return;
}
T* odata = data;
data = new T[n];
copy(odata, sz > n ? n: sz);
delete [] odata;
sz = n;
}
void copy(T* arr, unsigned n)
{
for(int i = 0; i < n; i++)
{
data[i] = arr[i];
}
}
void grow(unsigned new_sz)
{
unsigned nsz = sz;
if (nsz == 0)
{
nsz = 1;
}
while(nsz <= new_sz)
{
nsz *= 2;
}
resize(nsz);
}
void clone(const Array_data& a, unsigned n)
{
delete [] data;
data = new T[sz = a.sz];
copy(a.data, sz);
}
Array_data(const Array_data&);
Array_data& operator=(const Array_data&);
T* data;
unsigned sz;
int use;
};
///通过Pointer类访问Array对象元素
template<class T>
class Ptr_to_const
{
public:
Ptr_to_const(const Array<T>& a, unsigned n = 0):
ap(a.data), sub(n)
{
++ap->use;
}
Ptr_to_const():ap(0), sub(0){}
Ptr_to_const(const Ptr_to_const<T>& p):
ap(p.ap), sub(p.sub)
{
if (ap)
{
++ap->use;
}
}
~Ptr_to_const()
{
if (ap && --ap->use == 0)
{
delete ap;
}
}
Ptr_to_const& operator=(const Ptr_to_const<T>& p)
{
if (p.ap)
{
++p.ap->use;
}
if (ap&& --ap->use == 0)
{
delete ap;
}
ap = p.ap;
sub = p.sub;
return *this;
}
const T& operator*()const
{
if (ap == 0)
{
throw "* o unbound Ptr_to_const";
}
return (*ap)[sub];
}
private:
Array_data<T>* ap;
unsigned sub;
};
template<class T>
class Pointer:public Ptr_to_const<T>
{
public:
Pointer(Array<T>& a, unsigned n = 0):Ptr_to_const<T>(a, n){}
Pointer(Array<T>& a, unsigned n = 0):ap(&a), sub(n){}
Pointer():ap(0), sub(0){}
Pointer(){}
T operator*()const
{
if (ap == 0)
{
throw "* of unbound Pointer";
}
return (*ap)[sub];
}
void update(const T& t)
{
if (ap == 0)
{
throw "update of unbound Pointer";
}
(*ap)[sub] = t;
}
T operator[](unsigned n) const
{
if (n >= sz)
{
throw "Array subscripte out of range";
}
return data[n];
}
void update(unsigned n, const T& t)
{
if (n >= sz)
{
throw "Array subscript out of range";
}
data[n] = t;
}
T operator*() const
{
if (ap == 0)
{
throw "* of unbond Pointer";
}
return (*ap)[sub];
}
T& operator*()const
{
if (ap == 0)
{
throw "* of unbound Ptr_to_const";
}
return (*ap)[sub];
}
private:
Array<T>* ap;
unsigned sub;
};