[C++]2 D配列の下付き[][]を再ロードして2 Dマトリクスを実現

9871 ワード

[C++]2 D配列の下付き[][]を再ロードして2 Dマトリクスを実現
1.背景
実際のプロジェクトでは、2 Dデータを動的に割り当てる必要があることがよくあります.したがって,配列を割り当てて初期化するために手書きサイクルがしばしば必要となる.次のようになります.
//          
int** array = new int*[m];

//               
for (int i=0;ifor (int j=0;jarray[i] = new int[n];
    }

}

GSLなどのライブラリを利用して同じタスクを完了することができますが、私たちのプロジェクトでは2次元配列しか使用されず、複雑なマトリクス演算は必要ありません.2 D配列の代わりに1 D配列を使用する場合、array[i][j]で値を取ることはできず、2 D配列が直感的ではありません.2 D配列の使用を容易にするために,本論文では1 D配列を用いて[]を再ロードすることによって2 D行列を実現した.
2.分析
2 D配列の代わりに1 D配列でメモリを割り当て、連続したメモリ領域を取得します.[]を再ロードしてK行目のアドレスを返すことでarray[i][j]の方式で値をとることができる.
3.実現
#ifndef _MAT2_
#define _MAT2_
template <class T>
class Mat2
{
public:
    typedef T value_type;
    typedef T* pointer;
    typedef T* const pointer_conster;
    typedef const T& const_reference;
    typedef const T* const const_pointer_const;

public:
    typedef struct{
        int cols;
        int rows;
    }Size2;
    enum {ROW=1,COL=2};

public:
    /**
    *    
    *  :  rows、  cols     defaul
    *       rows*cols   ,      default
    */
    Mat2(const int rows,const int cols,const_reference default=0);
    /**
    *    
    *  :    n     defaul
    *       n*n   ,      default
    */
    Mat2(const int n, const_reference default=0);
    /**
    *      
    *  :  
    */
    Mat2(const Mat2& mat2);
    ~Mat2(void);

private:
    int rows;
    int cols;
    pointer array;

public:
    /**
    *     
    *    Size2  
    */
    const Size2 size();

    /**
    *     
    *    Mat2:ROW  Mat2:COL
    *    Mat2:ROW     ; Mat2:COL     ,    -1
    */
    const int size(int type) const;

    /**
    *      
    */
    const_pointer_const data(){return array;}

    /**
    *       
    */
    Mat2& operator=(const Mat2& mat);

    /**
    *  []   
    */
    pointer_conster operator[](const int k);

    // default     
    void fill(const_reference default);
};

//  :           ,   typename     ::           
template<class T>
Mat2::Mat2(const int m,const int n,typename Mat2::const_reference default)
    :rows(m),cols(n),array(new value_type[rows*cols])
{
    fill(default);
}

template<class T>
Mat2::Mat2(const int n,typename Mat2::const_reference default)
    :rows(n),cols(n),array(new value_type[n*n])
{
    fill(default);
}

template<class T>
Mat2::Mat2(const Mat2& mat)
{
    Mat2::Size2 size2 = mat.size();
    rows = size2.rows;
    cols = size2.cols;
    array = new value_type[rows*cols];
    memcpy(array,mat.data(),rows*cols*sizeof(value_type));
}

template<class T>
const typename Mat2::Size2 Mat2::size()
{
    Mat2::Size2 size2;
    size2.rows = rows;
    size2.cols = cols;
    return size2;
}

template<class T>
const int Mat2::size(int type) const
{
    switch(type)
    {
    case Mat2::ROW:
        return rows;
    case Mat2::COL:
        return cols;
    }
    return -1;
}

template<class T>
typename Mat2& Mat2::operator =(const Mat2& mat)
{
    if (this != &mat)//  :     
    {
        if (array)
        {
            delete[] array;
        }
        Mat2::Size2 size2 = mat.size();
        rows = size2.rows;
        cols = size2.cols;
        array = new value_type[rows*cols];
        memcpy(array,mat.data(),rows*cols*sizeof(value_type));
    }
    return *this;
}

//          k    ,     const            
template<class T>
typename Mat2::pointer_conster Mat2::operator[](const int k)
{
    return &(array[k*cols]);
}

template<class T>
void Mat2::fill(typename Mat2::const_reference default)
{
    for (int i=0;ifor (int j=0;jarray[i*cols+j] = default;
        }
    }
}

template<class T>
Mat2::~Mat2(void)
{
    if (array)
    {
        delete[] array;
    }
}

#endif // _MAT2_