template<class T>
class Array;
template<class T>
class Pointer;
template<class T>
class Array_data
{
friend class Array<T>;
friend class Pointer<T>;
Array_data(unsigned int n)
:data(new T[n])
,sz(n)
,use(1)
{
}
~Array_data(){ delete data; }
const 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];
}
Array_data(const Array_data&);
Array_data& operator=(const Array_data&);
private:
T* data;
unsigned int sz;
int use;
};
template<class T>
class Array
{
public:
Array(unsigned int n):data(new Array_data<T>(n))
{
}
~Array()
{
if (--data->use == 0)
{
delete data;
}
}
const T& operator[](unsigned int n)const
{
return (*data)[n];
}
T& operator[](unsigned int n)
{
return (*data)[n];
}
private:
Array(const Array&);
Array& operator=(const Array&);
Array_data<T>* data;
};
template<class T>
class Pointer /*: public Ptr_to_const<T>*/
{
public:
Pointer(Array<T>& a,unsigned n):ap(a.data),sub(n){ ++ap->use;}
Pointer():ap(0),sub(0)()
Pointer(const Pointer<T>& p)
:ap(p.ap)
,sub(p.sub)
{
if (p.ap)
{
++ap->use;
}
}
private:
Array_data<T>* ap;
unsigned sub;
};