《C++沉思录》第13章访问容器中的元素

/*

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;
};


 

 

 


 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值