继前天凑动态多维数组失败后,经指导,终于将其实现。
把数组的维度一并放在模板里,而不用构造函数来实现,于是定义Array看起来像下边这样,其中NewArray是一个全局变量:
Array<int, 3> a=NewArrary[3][2][1];   //相当于int[3][2][1]
operator[] 是利用特化类模板来实现的:
 template<typename _Type, int _DimensionCount>
template<typename _Type, int _DimensionCount>
 class Array
class Array


 {
{
 private:
private:
 _Type* Elements;
  _Type* Elements;
 int Size;
  int Size;
 public:
public:
 Array<_Type, DimensionCount-1> operator[](const int Index);
  Array<_Type, DimensionCount-1> operator[](const int Index);
 };
};

 template<typename _Type>
template<typename _Type>
 class Array<_Type, 1>
class Array<_Type, 1>


 {
{
 private:
private:
 _Type* Elements;
  _Type* Elements;
 int Size;
  int Size;
 public:
public:
 _Type& operator[](const int Index);
  _Type& operator[](const int Index);
 _Type operator[](const int Index)const;
  _Type operator[](const int Index)const;
 };
};在实现 Array<_Type, DimensionCount-1> operator[](const int Index) 时遇到一个问题,我需要返回一个Array<_Type, DimensionCount-1>,这个结果是根据当前的Array的信息来生成的,肯定需要用到private成员Elements,于是考虑用friend class Array<_Type, DimensionCount-1>,没想到编译器又喷我了,还是不能通过,原因不明T_T,无奈只能把Elements这些信息放到public下。
Array的测试用例如下:
 #include "Library/UnitTest/UnitTest.h"
#include "Library/UnitTest/UnitTest.h"
 #include "Library/Basic/Array.h"
#include "Library/Basic/Array.h"

 using namespace Lyt;
using namespace Lyt;

 void InitArray(int* a, const int Size)
void InitArray(int* a, const int Size)


 {
{
 if (a)
    if (a)

 
     {
{
 for (int i=0; i<=Size-1; i++) a[i]=i;
        for (int i=0; i<=Size-1; i++) a[i]=i;
 }
    }
 }
}

 bool CheckArray(int* a1, int* a2, const int Size)
bool CheckArray(int* a1, int* a2, const int Size)


 {
{
 if (a1 && a2)
    if (a1 && a2)

 
     {
{
 for (int i=0; i<=Size-1; i++)
        for (int i=0; i<=Size-1; i++)
 if (a1[i]!=a2[i]) return false;
            if (a1[i]!=a2[i]) return false;
 }
    }
 else if (a1 || a2) return false;
    else if (a1 || a2) return false;
 return true;
    return true;
 }
}

 TESTCASE(ArrayConstructorAssign, "ArrayConstructor")
TESTCASE(ArrayConstructorAssign, "ArrayConstructor")


 {
{
 int a[30];
    int a[30];
 InitArray(a, 30);
    InitArray(a, 30);
 int dims[3];
    int dims[3];
 dims[0]=2;
    dims[0]=2;
 dims[1]=3;
    dims[1]=3;
 dims[2]=5;
    dims[2]=5;

 Array<int, 3> a1;
    Array<int, 3> a1;
 EXPECT_TRUE(a1.Dimensions!=0, "DefaultConstructor");
    EXPECT_TRUE(a1.Dimensions!=0, "DefaultConstructor");
 Array<int, 3> a2=NewArray[2][3][5];
    Array<int, 3> a2=NewArray[2][3][5];
 InitArray(a2.Elements, a2.Size);
    InitArray(a2.Elements, a2.Size);
 EXPECT_TRUE(CheckArray(dims, a2.Dimensions, 3) && CheckArray(a, a2.Elements, a2.Size), "NewArrayConstructor");
    EXPECT_TRUE(CheckArray(dims, a2.Dimensions, 3) && CheckArray(a, a2.Elements, a2.Size), "NewArrayConstructor");
 Array<int, 3> a3=a2;
    Array<int, 3> a3=a2;
 EXPECT_TRUE(CheckArray(dims, a3.Dimensions, 3) && CheckArray(a, a3.Elements, a3.Size), "CopyConstructor");
    EXPECT_TRUE(CheckArray(dims, a3.Dimensions, 3) && CheckArray(a, a3.Elements, a3.Size), "CopyConstructor");
 Array<int, 2> a4=a3[1];
    Array<int, 2> a4=a3[1];
 EXPECT_TRUE(CheckArray(dims+1, a4.Dimensions, 2) && CheckArray(a+15, a4.Elements, a4.Size), "CopyConstructor operator[]");
    EXPECT_TRUE(CheckArray(dims+1, a4.Dimensions, 2) && CheckArray(a+15, a4.Elements, a4.Size), "CopyConstructor operator[]");
 Array<int, 1> a5=a3[1][1];
    Array<int, 1> a5=a3[1][1];
 EXPECT_TRUE(CheckArray(dims+2, a5.Dimensions, 1) && CheckArray(a+20, a5.Elements, a5.Size), "CopyConstructor operator[]");
    EXPECT_TRUE(CheckArray(dims+2, a5.Dimensions, 1) && CheckArray(a+20, a5.Elements, a5.Size), "CopyConstructor operator[]");
 Array<int, 1> a6=a5;
    Array<int, 1> a6=a5;
 EXPECT_TRUE(CheckArray(dims+2, a6.Dimensions, 1) && CheckArray(a+20, a6.Elements, a6.Size), "CopyConstructor");
    EXPECT_TRUE(CheckArray(dims+2, a6.Dimensions, 1) && CheckArray(a+20, a6.Elements, a6.Size), "CopyConstructor");

 EXPECT_TRUE(a2[1][1][0]==20, "operator[]");
    EXPECT_TRUE(a2[1][1][0]==20, "operator[]");
 EXPECT_TRUE((a2[1][1][0]=30)==30, "operator=");
    EXPECT_TRUE((a2[1][1][0]=30)==30, "operator=");
 }
}

 TESTCASE(ArrayAssign, "Array::operator=")
TESTCASE(ArrayAssign, "Array::operator=")


 {
{
 int a1[30];
    int a1[30];
 InitArray(a1, 30);
    InitArray(a1, 30);
 int dims1[3];
    int dims1[3];
 dims1[0]=2;
    dims1[0]=2;
 dims1[1]=3;
    dims1[1]=3;
 dims1[2]=5;
    dims1[2]=5;

 int a2[8];
    int a2[8];
 InitArray(a2, 8);
    InitArray(a2, 8);
 int dims2[3];
    int dims2[3];
 dims2[0]=2;
    dims2[0]=2;
 dims2[1]=2;
    dims2[1]=2;
 dims2[2]=2;
    dims2[2]=2;

 Array<int, 3> Array1=NewArray[2][3][5];
    Array<int, 3> Array1=NewArray[2][3][5];
 InitArray(Array1.Elements, Array1.Size);
    InitArray(Array1.Elements, Array1.Size);
 Array<int, 3> Array2=Array1;
    Array<int, 3> Array2=Array1;

 Array<int, 3> Array3=NewArray[2][2][2];
    Array<int, 3> Array3=NewArray[2][2][2];
 InitArray(Array3.Elements, Array3.Size);
    InitArray(Array3.Elements, Array3.Size);
 Array1=Array3;
    Array1=Array3;
 EXPECT_TRUE(CheckArray(dims2, Array1.Dimensions, 3) && CheckArray(a2, Array1.Elements, Array1.Size), "operator=");
    EXPECT_TRUE(CheckArray(dims2, Array1.Dimensions, 3) && CheckArray(a2, Array1.Elements, Array1.Size), "operator=");
 EXPECT_TRUE(Array1[0][1][1]==3, "operator[]");
    EXPECT_TRUE(Array1[0][1][1]==3, "operator[]");

 Array<int, 2> Array4=Array1[0];
    Array<int, 2> Array4=Array1[0];
 Array<int, 1> Array5=Array1[0][1];
    Array<int, 1> Array5=Array1[0][1];
 Array5[1]=9;
    Array5[1]=9;
 EXPECT_TRUE(Array1[0][1][1]==9 && Array3[0][1][1]==9 && Array4[1][1]==9, "operator=");
    EXPECT_TRUE(Array1[0][1][1]==9 && Array3[0][1][1]==9 && Array4[1][1]==9, "operator=");

 Array3=Array2;
    Array3=Array2;
 EXPECT_TRUE(CheckArray(dims1, Array3.Dimensions, 3) && CheckArray(a1, Array3.Elements, Array3.Size), "operator=");
    EXPECT_TRUE(CheckArray(dims1, Array3.Dimensions, 3) && CheckArray(a1, Array3.Elements, Array3.Size), "operator=");
 }
}

 TESTCASE(ArrayClone, "Array::Clone")
TESTCASE(ArrayClone, "Array::Clone")


 {
{
 int a[30];
    int a[30];
 InitArray(a, 30);
    InitArray(a, 30);
 int dims[3];
    int dims[3];
 dims[0]=2;
    dims[0]=2;
 dims[1]=3;
    dims[1]=3;
 dims[2]=5;
    dims[2]=5;

 Array<int, 3> a1=NewArray[2][3][5];
    Array<int, 3> a1=NewArray[2][3][5];
 InitArray(a1.Elements, a1.Size);
    InitArray(a1.Elements, a1.Size);
 Array<int, 3> a2=a1.Clone();
    Array<int, 3> a2=a1.Clone();
 EXPECT_TRUE(CheckArray(dims, a2.Dimensions, 3) && CheckArray(a, a2.Elements, a2.Size), "Clone");
    EXPECT_TRUE(CheckArray(dims, a2.Dimensions, 3) && CheckArray(a, a2.Elements, a2.Size), "Clone");
 a1[0][0][0]=100;
    a1[0][0][0]=100;
 EXPECT_TRUE(a1[0][0][0]==100 && a2[0][0][0]==0, "operator=");
    EXPECT_TRUE(a1[0][0][0]==100 && a2[0][0][0]==0, "operator=");
 }
}

Array源码:
 #ifndef ARRAY_H
#ifndef ARRAY_H
 #define ARRAY_H
#define ARRAY_H

 #include <memory.h>
#include <memory.h>

 namespace Lyt
namespace Lyt


 {
{
 template<int _DimensionCount>
    template<int _DimensionCount>
 class ArrayDimension
    class ArrayDimension

 
     {
{
 public:
    public:
 int Data[_DimensionCount+1];
        int Data[_DimensionCount+1];

 ArrayDimension()
        ArrayDimension()

 
         {
{
 for (int i=0; i<=_DimensionCount-1; i++) Data[i]=0;
            for (int i=0; i<=_DimensionCount-1; i++) Data[i]=0;
 }
        }

 ArrayDimension(const int Dimension, int* PrevDimensions)
        ArrayDimension(const int Dimension, int* PrevDimensions)

 
         {
{
 Data[_DimensionCount-1]=Dimension;
            Data[_DimensionCount-1]=Dimension;
 memcpy(Data, PrevDimensions, sizeof(int)*(_DimensionCount-1));
            memcpy(Data, PrevDimensions, sizeof(int)*(_DimensionCount-1));
 }
        }

 ArrayDimension<_DimensionCount+1> operator[](const int Dimension)
        ArrayDimension<_DimensionCount+1> operator[](const int Dimension)

 
         {
{
 return ArrayDimension<_DimensionCount+1>(Dimension, Data);
            return ArrayDimension<_DimensionCount+1>(Dimension, Data);
 }
        }

 int GetSize()const
        int GetSize()const

 
         {
{
 int Result=1;
            int Result=1;
 for (int i=0; i<=_DimensionCount-1; i++) Result*=Data[i];
            for (int i=0; i<=_DimensionCount-1; i++) Result*=Data[i];
 return Result;
            return Result;
 }
        }
 };
    };

 extern ArrayDimension<0> NewArray;
    extern ArrayDimension<0> NewArray; 

 template<typename _Type, int _DimensionCount>
    template<typename _Type, int _DimensionCount>
 class Array
    class Array

 
     {
{
 protected:
    protected:
 void RefIncrease()
        void RefIncrease()

 
         {
{
 if (RefCount) (*RefCount)++;
            if (RefCount) (*RefCount)++;
 }
        }

 void RefDecrease()
        void RefDecrease()

 
         {
{
 if (RefCount)
            if (RefCount)

 
             {
{
 if (--(*RefCount)==0)
                if (--(*RefCount)==0)

 
                 {
{
 delete RefCount;
                    delete RefCount;
 delete[] (Dimensions-DimensionsIndex);
                    delete[] (Dimensions-DimensionsIndex);
 if (Elements) delete[] (Elements-ElementsIndex);
                    if (Elements) delete[] (Elements-ElementsIndex);
 RefCount=0;
                    RefCount=0;
 Dimensions=0;
                    Dimensions=0;
 Elements=0;
                    Elements=0;
 Size=0;
                    Size=0;
 ElementsIndex=0;
                    ElementsIndex=0;
 DimensionsIndex=0;
                    DimensionsIndex=0;
 }
                }
 }
            }
 }
        }
 
    
 public:
    public:
 int* RefCount;
        int* RefCount;
 int* Dimensions;
        int* Dimensions;
 _Type* Elements;
        _Type* Elements;
 int Size;
        int Size;
 int ElementsIndex;
        int ElementsIndex;
 int DimensionsIndex;
        int DimensionsIndex;

 Array()
        Array()

 
         {
{
 RefCount=new int(1);
            RefCount=new int(1);
 Dimensions=new int[_DimensionCount];
            Dimensions=new int[_DimensionCount];
 Elements=0;
            Elements=0;
 Size=0;
            Size=0;
 ElementsIndex=0;
            ElementsIndex=0;
 DimensionsIndex=0;
            DimensionsIndex=0;
 }
        }

 Array(const Array<_Type, _DimensionCount>& Object)
        Array(const Array<_Type, _DimensionCount>& Object)

 
         {
{
 RefCount=Object.RefCount;
            RefCount=Object.RefCount;
 Dimensions=Object.Dimensions;
            Dimensions=Object.Dimensions;
 Elements=Object.Elements;
            Elements=Object.Elements;
 Size=Object.Size;
            Size=Object.Size;
 ElementsIndex=Object.ElementsIndex;
            ElementsIndex=Object.ElementsIndex;
 DimensionsIndex=Object.DimensionsIndex;
            DimensionsIndex=Object.DimensionsIndex;
 RefIncrease();
            RefIncrease();
 }
        }

 Array(const ArrayDimension<_DimensionCount> Dims)
        Array(const ArrayDimension<_DimensionCount> Dims)

 
         {
{
 RefCount=new int(1);
            RefCount=new int(1);
 Dimensions=new int[_DimensionCount];
            Dimensions=new int[_DimensionCount];
 memcpy(Dimensions, Dims.Data, sizeof(int)*_DimensionCount);
            memcpy(Dimensions, Dims.Data, sizeof(int)*_DimensionCount);
 Size=Dims.GetSize();
            Size=Dims.GetSize();
 Elements=new _Type[Size];
            Elements=new _Type[Size];
 ElementsIndex=0;
            ElementsIndex=0;
 DimensionsIndex=0;
            DimensionsIndex=0;
 }
        }

 ~Array()
        ~Array()

 
         {
{
 RefDecrease();
            RefDecrease();
 }
        }

 Array<_Type, _DimensionCount>& operator=(const Array<_Type, _DimensionCount>& Object)
        Array<_Type, _DimensionCount>& operator=(const Array<_Type, _DimensionCount>& Object)

 
         {
{
 RefDecrease();
            RefDecrease();
 RefCount=Object.RefCount;
            RefCount=Object.RefCount;
 Dimensions=Object.Dimensions;
            Dimensions=Object.Dimensions;
 Elements=Object.Elements;
            Elements=Object.Elements;
 Size=Object.Size;
            Size=Object.Size;
 ElementsIndex=Object.ElementsIndex;
            ElementsIndex=Object.ElementsIndex;
 DimensionsIndex=Object.DimensionsIndex;
            DimensionsIndex=Object.DimensionsIndex;
 RefIncrease();
            RefIncrease();
 return *this;
            return *this;
 }
        }

 Array<_Type, _DimensionCount-1> operator[](const int Index)
        Array<_Type, _DimensionCount-1> operator[](const int Index)

 
         {
{
 RefIncrease();
            RefIncrease();
 Array<_Type, _DimensionCount-1> Result;
            Array<_Type, _DimensionCount-1> Result;
 delete Result.RefCount;
            delete Result.RefCount;
 Result.RefCount=RefCount;
            Result.RefCount=RefCount;
 Result.Size=Size/Dimensions[0];
            Result.Size=Size/Dimensions[0];
 Result.Dimensions=Dimensions+1;
            Result.Dimensions=Dimensions+1;
 Result.Elements=Elements+Index*Result.Size;
            Result.Elements=Elements+Index*Result.Size;
 Result.ElementsIndex=ElementsIndex+Index*Result.Size;
            Result.ElementsIndex=ElementsIndex+Index*Result.Size;
 Result.DimensionsIndex=DimensionsIndex+1;
            Result.DimensionsIndex=DimensionsIndex+1;
 return Result;
            return Result;
 }
        }

 Array<_Type, _DimensionCount> Clone()const
        Array<_Type, _DimensionCount> Clone()const

 
         {
{
 Array<_Type, _DimensionCount> Result;
            Array<_Type, _DimensionCount> Result;
 memcpy(Result.Dimensions, Dimensions, sizeof(int)*(_DimensionCount));
            memcpy(Result.Dimensions, Dimensions, sizeof(int)*(_DimensionCount));
 Result.Size=Size;
            Result.Size=Size;
 Result.Elements=new _Type[Size];
            Result.Elements=new _Type[Size];
 memcpy(Result.Elements, Elements, sizeof(int)*(Size));
            memcpy(Result.Elements, Elements, sizeof(int)*(Size));
 return Result;
            return Result;
 }
        }
 };
    };

 template<typename _Type>
    template<typename _Type>
 class Array<_Type, 1>
    class Array<_Type, 1>

 
     {
{
 protected:
    protected:
 void RefIncrease()
        void RefIncrease()

 
         {
{
 if (RefCount) (*RefCount)++;
            if (RefCount) (*RefCount)++;
 }
        }

 void RefDecrease()
        void RefDecrease()

 
         {
{
 if (RefCount)
            if (RefCount)

 
             {
{
 if (--(*RefCount)==0)
                if (--(*RefCount)==0)

 
                 {
{
 delete RefCount;
                    delete RefCount;
 delete[] (Dimensions-DimensionsIndex);
                    delete[] (Dimensions-DimensionsIndex);
 if (Elements) delete[] (Elements-ElementsIndex);
                    if (Elements) delete[] (Elements-ElementsIndex);
 RefCount=0;
                    RefCount=0;
 Dimensions=0;
                    Dimensions=0;
 Elements=0;
                    Elements=0;
 Size=0;
                    Size=0;
 ElementsIndex=0;
                    ElementsIndex=0;
 DimensionsIndex=0;
                    DimensionsIndex=0;
 }
                }
 }
            }
 }
        }
 
    
 public:
    public:
 int* RefCount;
        int* RefCount;
 int* Dimensions;
        int* Dimensions;
 _Type* Elements;
        _Type* Elements;
 int Size;
        int Size;
 int ElementsIndex;
        int ElementsIndex;
 int DimensionsIndex;
        int DimensionsIndex;

 Array()
        Array()

 
         {
{
 RefCount=new int(1);
            RefCount=new int(1);
 Dimensions=new int[1];
            Dimensions=new int[1];
 Elements=0;
            Elements=0;
 Size=0;
            Size=0;
 ElementsIndex=0;
            ElementsIndex=0;
 DimensionsIndex=0;
            DimensionsIndex=0;
 }
        }

 Array(const Array<_Type, 1>& Object)
        Array(const Array<_Type, 1>& Object)

 
         {
{
 RefCount=Object.RefCount;
            RefCount=Object.RefCount;
 Dimensions=Object.Dimensions;
            Dimensions=Object.Dimensions;
 Elements=Object.Elements;
            Elements=Object.Elements;
 Size=Object.Size;
            Size=Object.Size;
 ElementsIndex=Object.ElementsIndex;
            ElementsIndex=Object.ElementsIndex;
 DimensionsIndex=Object.DimensionsIndex;
            DimensionsIndex=Object.DimensionsIndex;
 RefIncrease();
            RefIncrease();
 }
        }

 Array(const ArrayDimension<1> Dims)
        Array(const ArrayDimension<1> Dims)

 
         {
{
 RefCount=new int(1);
            RefCount=new int(1);
 Dimensions=new int[];
            Dimensions=new int[];
 memcpy(Dimensions, Dims.Data, sizeof(int));
            memcpy(Dimensions, Dims.Data, sizeof(int));
 Size=Dims.GetSize();
            Size=Dims.GetSize();
 Elements=new _Type[Size];
            Elements=new _Type[Size];
 ElementsIndex=0;
            ElementsIndex=0;
 DimensionsIndex=0;
            DimensionsIndex=0;
 }
        }

 ~Array()
        ~Array()

 
         {
{
 RefDecrease();
            RefDecrease();
 }
        }

 Array<_Type, 1>& operator=(const Array<_Type, 1>& Object)
        Array<_Type, 1>& operator=(const Array<_Type, 1>& Object)

 
         {
{
 RefDecrease();
            RefDecrease();
 RefCount=Object.RefCount;
            RefCount=Object.RefCount;
 Dimensions=Object.Dimensions;
            Dimensions=Object.Dimensions;
 Elements=Object.Elements;
            Elements=Object.Elements;
 Size=Object.Size;
            Size=Object.Size;
 ElementsIndex=Object.ElementsIndex;
            ElementsIndex=Object.ElementsIndex;
 DimensionsIndex=Object.DimensionsIndex;
            DimensionsIndex=Object.DimensionsIndex;
 RefIncrease();
            RefIncrease();
 return *this;
            return *this;
 }
        }

 _Type& operator[](const int Index)
        _Type& operator[](const int Index)

 
         {
{
 if (Index<0 || Index>=Dimensions[0]) throw L"越界访问";
            if (Index<0 || Index>=Dimensions[0]) throw L"越界访问";
 else return Elements[Index];
            else return Elements[Index];
 }
        }

 _Type operator[](const int Index)const
        _Type operator[](const int Index)const

 
         {
{
 if (Index<0 || Index>=Dimensions[0]) throw L"越界访问";
            if (Index<0 || Index>=Dimensions[0]) throw L"越界访问";
 else return Elements[Index];
            else return Elements[Index];
 }
        }

 Array<_Type, 1> Clone()const
        Array<_Type, 1> Clone()const

 
         {
{
 Array<_Type, 1> Result;
            Array<_Type, 1> Result;
 mencpy(Result.Dimensions, Dimensions, sizeof(int));
            mencpy(Result.Dimensions, Dimensions, sizeof(int));
 Result.Size=Size;
            Result.Size=Size;
 Result.Elements=new _Type[Size];
            Result.Elements=new _Type[Size];
 memcpy(Result.Elements, Elements, sizeof(int)*(Size));
            memcpy(Result.Elements, Elements, sizeof(int)*(Size));
 return Result;
            return Result;
 }
        }
 };
    };
 }
}

 #endif
#endif
欢迎各位继续喷~
	
posted on 2009-10-13 14:16 
Lyt 阅读(1769) 
评论(9)  编辑 收藏 引用  所属分类: 
数据结构