• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            Lyt
            posts - 16,comments - 61,trackbacks - 0

            繼前天湊動態多維數組失敗后,經指導,終于將其實現。

            把數組的維度一并放在模板里,而不用構造函數來實現,于是定義Array看起來像下邊這樣,其中NewArray是一個全局變量:

            Array<int3> a=NewArrary[3][2][1];   //相當于int[3][2][1]

            operator[] 是利用特化類模板來實現的:

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

            template
            <typename _Type>
            class Array<_Type, 1>
            {
            private:
              _Type
            * Elements;
              
            int Size;
            public:
              _Type
            & operator[](const int Index);
              _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/Basic/Array.h"

            using namespace Lyt;

            void InitArray(int* a, const int Size)
            {
                
            if (a)
                
            {
                    
            for (int i=0; i<=Size-1; i++) a[i]=i;
                }

            }


            bool CheckArray(int* a1, int* a2, const int Size)
            {
                
            if (a1 && a2)
                
            {
                    
            for (int i=0; i<=Size-1; i++)
                        
            if (a1[i]!=a2[i]) return false;
                }

                
            else if (a1 || a2) return false;
                
            return true;
            }


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

                Array
            <int3> a1;
                EXPECT_TRUE(a1.Dimensions
            !=0"DefaultConstructor");
                Array
            <int3> a2=NewArray[2][3][5];
                InitArray(a2.Elements, a2.Size);
                EXPECT_TRUE(CheckArray(dims, a2.Dimensions, 
            3&& CheckArray(a, a2.Elements, a2.Size), "NewArrayConstructor");
                Array
            <int3> a3=a2;
                EXPECT_TRUE(CheckArray(dims, a3.Dimensions, 
            3&& CheckArray(a, a3.Elements, a3.Size), "CopyConstructor");
                Array
            <int2> a4=a3[1];
                EXPECT_TRUE(CheckArray(dims
            +1, a4.Dimensions, 2&& CheckArray(a+15, a4.Elements, a4.Size), "CopyConstructor operator[]");
                Array
            <int1> a5=a3[1][1];
                EXPECT_TRUE(CheckArray(dims
            +2, a5.Dimensions, 1&& CheckArray(a+20, a5.Elements, a5.Size), "CopyConstructor operator[]");
                Array
            <int1> a6=a5;
                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]=30)==30"operator=");
            }


            TESTCASE(ArrayAssign, 
            "Array::operator=")
            {
                
            int a1[30];
                InitArray(a1, 
            30);
                
            int dims1[3];
                dims1[
            0]=2;
                dims1[
            1]=3;
                dims1[
            2]=5;

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

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

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

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

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


            TESTCASE(ArrayClone, 
            "Array::Clone")
            {
                
            int a[30];
                InitArray(a, 
            30);
                
            int dims[3];
                dims[
            0]=2;
                dims[
            1]=3;
                dims[
            2]=5;

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

            Array源碼:

            #ifndef ARRAY_H
            #define ARRAY_H

            #include 
            <memory.h>

            namespace Lyt
            {
                template
            <int _DimensionCount>
                
            class ArrayDimension
                
            {
                
            public:
                    
            int Data[_DimensionCount+1];

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


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


                    ArrayDimension
            <_DimensionCount+1> operator[](const int Dimension)
                    
            {
                        
            return ArrayDimension<_DimensionCount+1>(Dimension, Data);
                    }


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

                }
            ;

                
            extern ArrayDimension<0> NewArray; 

                template
            <typename _Type, int _DimensionCount>
                
            class Array
                
            {
                
            protected:
                    
            void RefIncrease()
                    
            {
                        
            if (RefCount) (*RefCount)++;
                    }


                    
            void RefDecrease()
                    
            {
                        
            if (RefCount)
                        
            {
                            
            if (--(*RefCount)==0)
                            
            {
                                delete RefCount;
                                delete[] (Dimensions
            -DimensionsIndex);
                                
            if (Elements) delete[] (Elements-ElementsIndex);
                                RefCount
            =0;
                                Dimensions
            =0;
                                Elements
            =0;
                                Size
            =0;
                                ElementsIndex
            =0;
                                DimensionsIndex
            =0;
                            }

                        }

                    }

                
                
            public:
                    
            int* RefCount;
                    
            int* Dimensions;
                    _Type
            * Elements;
                    
            int Size;
                    
            int ElementsIndex;
                    
            int DimensionsIndex;

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


                    Array(
            const Array<_Type, _DimensionCount>& Object)
                    
            {
                        RefCount
            =Object.RefCount;
                        Dimensions
            =Object.Dimensions;
                        Elements
            =Object.Elements;
                        Size
            =Object.Size;
                        ElementsIndex
            =Object.ElementsIndex;
                        DimensionsIndex
            =Object.DimensionsIndex;
                        RefIncrease();
                    }


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


                    
            ~Array()
                    
            {
                        RefDecrease();
                    }


                    Array
            <_Type, _DimensionCount>& operator=(const Array<_Type, _DimensionCount>& Object)
                    
            {
                        RefDecrease();
                        RefCount
            =Object.RefCount;
                        Dimensions
            =Object.Dimensions;
                        Elements
            =Object.Elements;
                        Size
            =Object.Size;
                        ElementsIndex
            =Object.ElementsIndex;
                        DimensionsIndex
            =Object.DimensionsIndex;
                        RefIncrease();
                        
            return *this;
                    }


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


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

                }
            ;

                template
            <typename _Type>
                
            class Array<_Type, 1>
                
            {
                
            protected:
                    
            void RefIncrease()
                    
            {
                        
            if (RefCount) (*RefCount)++;
                    }


                    
            void RefDecrease()
                    
            {
                        
            if (RefCount)
                        
            {
                            
            if (--(*RefCount)==0)
                            
            {
                                delete RefCount;
                                delete[] (Dimensions
            -DimensionsIndex);
                                
            if (Elements) delete[] (Elements-ElementsIndex);
                                RefCount
            =0;
                                Dimensions
            =0;
                                Elements
            =0;
                                Size
            =0;
                                ElementsIndex
            =0;
                                DimensionsIndex
            =0;
                            }

                        }

                    }

                
                
            public:
                    
            int* RefCount;
                    
            int* Dimensions;
                    _Type
            * Elements;
                    
            int Size;
                    
            int ElementsIndex;
                    
            int DimensionsIndex;

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


                    Array(
            const Array<_Type, 1>& Object)
                    
            {
                        RefCount
            =Object.RefCount;
                        Dimensions
            =Object.Dimensions;
                        Elements
            =Object.Elements;
                        Size
            =Object.Size;
                        ElementsIndex
            =Object.ElementsIndex;
                        DimensionsIndex
            =Object.DimensionsIndex;
                        RefIncrease();
                    }


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


                    
            ~Array()
                    
            {
                        RefDecrease();
                    }


                    Array
            <_Type, 1>& operator=(const Array<_Type, 1>& Object)
                    
            {
                        RefDecrease();
                        RefCount
            =Object.RefCount;
                        Dimensions
            =Object.Dimensions;
                        Elements
            =Object.Elements;
                        Size
            =Object.Size;
                        ElementsIndex
            =Object.ElementsIndex;
                        DimensionsIndex
            =Object.DimensionsIndex;
                        RefIncrease();
                        
            return *this;
                    }


                    _Type
            & operator[](const int Index)
                    
            {
                        
            if (Index<0 || Index>=Dimensions[0]) throw L"越界訪問";
                        
            else return Elements[Index];
                    }


                    _Type 
            operator[](const int Index)const
                    
            {
                        
            if (Index<0 || Index>=Dimensions[0]) throw L"越界訪問";
                        
            else return Elements[Index];
                    }


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

                }
            ;
            }


            #endif
            歡迎各位繼續噴~
            posted on 2009-10-13 14:16 Lyt 閱讀(1735) 評論(9)  編輯 收藏 引用 所屬分類: 數據結構

            FeedBack:
            # re: 很傻很天真之Array——解決方法
            2009-10-13 16:34 | 遠古毛利人
            樓主可以參考一下boost::multiarray的實現  回復  更多評論
              
            # re: 很傻很天真之Array——解決方法
            2009-10-13 17:32 | 陳梓瀚(vczh)
            應該是讓Array的構造函數接受多一點東西才對,而不是把什么都放到public里面。  回復  更多評論
              
            # re: 很傻很天真之Array——解決方法
            2009-10-13 17:38 | 陳梓瀚(vczh)
            而且你的Array<i>想用Array<i-1>的時候,應該在Array<i>里面friend那個Array<i+1>才對,怎么能friend那個Array<-1>呢,你搞反了。  回復  更多評論
              
            # re: 很傻很天真之Array——解決方法
            2009-10-13 20:11 | 陳昱(CY)
            很強大,接下來應該實現tuple了  回復  更多評論
              
            # re: 很傻很天真之Array——解決方法
            2009-10-14 11:38 | 欲三更
            再來個迭代器吧, 這樣就能方便使用那些算法了.  回復  更多評論
              
            # re: 很傻很天真之Array——解決方法
            2009-10-14 16:22 | 暗涌
            不錯,學習了
            另外:
            Array<_Type, 1> Clone()const
            {
            Array<_Type, 1> Result;
            mencpy(Result.Dimensions, Dimensions, sizeof(int)); // memcpy筆誤了
            Result.Size=Size;
            Result.Elements=new _Type[Size];
            memcpy(Result.Elements, Elements, sizeof(int)*(Size));
            return Result;
            }

              回復  更多評論
              
            # re: 很傻很天真之Array——解決方法
            2009-10-14 16:37 | 暗涌
            lz,我用friend class Array<_Type, _DimensionCount-1>是可以的哦,但是要記住在特化的Array里面也要加friend class Array<_Type, 0>  回復  更多評論
              
            # re: 很傻很天真之Array——解決方法
            2009-10-14 16:40 | 伊莎貝兒女裝
            是的數據庫反反復復反反復復  回復  更多評論
              
            # re: 很傻很天真之Array——解決方法
            2009-10-14 16:44 | 暗涌
            @暗涌
            Sorry, 之前沒有做訪問操作,確實不行,用+1也不行  回復  更多評論
              
            久久综合亚洲色一区二区三区| 国产成人无码精品久久久久免费| 亚洲狠狠婷婷综合久久蜜芽| 久久综合给久久狠狠97色 | 亚洲精品国产自在久久| 性做久久久久久久久久久| 漂亮人妻被黑人久久精品| 国内精品久久久久久久影视麻豆 | 久久久久亚洲AV无码观看 | 精品久久久久久久国产潘金莲 | 亚洲av成人无码久久精品 | 久久99精品国产一区二区三区| 久久久WWW成人免费精品| 久久久久成人精品无码中文字幕 | 久久99热这里只有精品国产 | 久久综合伊人77777| 久久精品国产免费| 欧美噜噜久久久XXX| 久久亚洲精品国产精品婷婷| 欧美777精品久久久久网| 国产69精品久久久久APP下载| 国产成人精品久久亚洲高清不卡| 无码精品久久久久久人妻中字| 欧美日韩精品久久久久| 亚洲国产精品久久久久久| 久久99国产综合精品| 五月丁香综合激情六月久久| 久久婷婷五月综合97色直播| 久久久久久亚洲精品不卡| 久久99精品国产99久久6| 伊人热人久久中文字幕| 久久久久一区二区三区| 狠狠干狠狠久久| 亚洲一区二区三区日本久久九| 国产午夜福利精品久久2021 | 久久久久久久波多野结衣高潮| 久久人人爽人人爽人人片AV麻豆| 91秦先生久久久久久久| 国产亚州精品女人久久久久久| 久久美女网站免费| 国产69精品久久久久9999|