Proxy Class(代理类)

        在使用二维数组时,我们可以使用a[][]来访问数组中的元素,这很显然是正确的也无需证明。

        但如果要自己实现一个二维数组的时候,会发现如果想要重载符号[][],会被告知没有这个符号,这即引出了C++ oop设计方式中的一种proxy class方式。

        proxy class即在一个class中,嵌套的声明了另一个class,利用了这个隐藏的嵌套class以实现一些特殊技巧。

        回到二维数组中来,我们已知没有[][]这种链式访问结构的符号,但是C++又允许我们这样做,显然它实现时有某种技巧。

        把二维数组拆分来看,其中我们知道,a[posi]是合法的,而我们常用的是a[posi1][posi2],把前半段拆开来看就是

        ( a[posi1] ) [posi2]

        也就是说并没有什么二维数组,实际上是两个一维数组,其中第一个一维数组中保存了一些一维数组对象,内部的一维数组中保存了一个数

        对应关系即:a[posi] –>  _array(一个隐藏的对象) –> _array[posi2] 保存了一个值

        以下是一个简略的代码实现(有BUG,见后方)

template<typename T>
class Array2D
{
private:
    //the proxy class
    class Array1D
    {
    private:int _cap = 10;
        T* _elemNum = new T[_cap];
    public:
        Array1D(int inx)
        {
            _elemNum = new T[inx];
        }
        T& operator [](int posi)
        {
            return _elemNum[posi];
        }
        const T& operator [](const int posi) const
        {
            return _elemNum[posi];
        }
    };
    const int _cap = 10;
    Array1D* _elemArray = new Array1D[_cap];
public:
    Array2D(int inx1, int inx2)
    {
        Array1D* _elemArray = new Array1D[inx1];
        for (int i = 0; i < inx1; i++)
        {
            Array1D* _tmpArray = new Array1D[inx2];
            _elemArray[i] = *_tmpArray;
        }
    }

    Array1D& operator [](int posi)
    {
        return _elemArray[posi];
    }
};

        区分两种数组:_elemArray用于储存匿名的函数对象,_elemNum用于储存实际的值。

        proxy class在此处的实际意义就在于,其实现只在另一个class内使用,也只提供给他使用,类似于class的一个代理一样,负责处理内部事务。

        注意其中Array2D的重载[]函数:

 

Array1D& operator [](int posi)
    {
        return _elemArray[posi];
    }

        返回的是一个Array1D对象的引用,那么实际调用时:

        a[inx1][inx2] = …; a[inx1]部分返回了一个Array1D对象,为了方便现假定其名称为_array 故有:

        a[inx1][inx2] –> _array[inx2]

       

        同时这里还需要引出一个BUG,当这段代码实际运行的时候会提示:Array1D没有合适的默认构造函数可用,解决办法是给Array1D类一个没有参数的构造函数,即使它什么也不写也可以,具体原因请参见:https://www.cnblogs.com/HotPants/p/11421065.html

posted @ 2019-08-28 14:12  随处可见的阿宅  阅读(1319)  评论(0编辑  收藏  举报