矩阵类,二维数组

      实现一个矩阵类,重载下标操作符, 即 m[i][j],  以及其它运算符

   1:   
   2:  //重载下标操作符, m[i][j], 方法1:
   3:  #pragma once
   4:  #include <iostream>
   5:  #include <cstddef>
   6:  #include <cassert>
   7:   
   8:  template<typename T, std::size_t ROW = 10, std::size_t COLUMN = 10>
   9:  class Matrix
  10:  {
  11:  private:
  12:      std::size_t _ROW;
  13:      std::size_t _COLUMN;
  14:      T* pData;
  15:   
  16:  public:
  17:      Matrix();
  18:      Matrix(std::size_t M, std::size_t N);
  19:      ~Matrix();
  20:   
  21:      //重载下标运算符,实现 a[m][n]
  22:      T* operator[](std::size_t m);
  23:      const T* operator[](std::size_t m) const;
  24:      
  25:      //提供 a(m, n) 这样的操作
  26:      T& operator()(std::size_t m, std::size_t n);
  27:      const T& operator()(std::size_t m, std::size_t n) const;
  28:   
  29:      //拷贝构造
  30:      Matrix(const Matrix<T>& m);
  31:      //重载 =
  32:      Matrix<T>& operator=(const Matrix<T>& m);
  33:   
  34:      //重载 +=
  35:      Matrix<T>& operator+=(const Matrix<T>& m);
  36:   
  37:      //重载 +, -, *
  38:      Matrix<T> operator+(const Matrix<T>& m);
  39:      Matrix<T> operator-(const Matrix<T>& m);
  40:      Matrix<T> operator*(const Matrix<T>& m);
  41:   
  42:      //矩阵转置 !
  43:      Matrix<T> operator!();
  44:   
  45:      //求反 -
  46:      Matrix<T>& operator-();
  47:   
  48:      //显示矩阵
  49:      void displayMatrix() const;
  50:   
  51:      //取得行, 列的大小
  52:      const std::size_t getRow() const;
  53:      const std::size_t getColumn() const;
  54:   
  55:      //注: 重载 << 时, template<typename T1> 必须和 模板类中的类型不一样
  56:      template<typename T1>
  57:      friend std::ostream& operator<<(std::ostream& os, const Matrix<T1>& m);
  58:  };
  59:   
  60:  //默认构造函数
  61:  template<typename T, std::size_t ROW, std::size_t COLUMN>
  62:  Matrix<T, ROW, COLUMN>::Matrix():_ROW(ROW),_COLUMN(COLUMN)
  63:  {
  64:      pData = new T[_ROW*_COLUMN];
  65:      assert(pData);
  66:      memset(pData, 0, _ROW*_COLUMN*sizeof(T));
  67:  }
  68:  //有参构造函数
  69:  template<typename T, std::size_t ROW, std::size_t COLUMN>
  70:  Matrix<T, ROW, COLUMN>::Matrix(std::size_t M, std::size_t N)
  71:                      :_ROW(M), _COLUMN(N)
  72:  {
  73:      pData = new T[_ROW*_COLUMN];
  74:      assert(pData);
  75:      memset(pData, 0, _ROW*_COLUMN*sizeof(T));
  76:  }
  77:   
  78:  //析构函数
  79:  template<typename T, std::size_t ROW, std::size_t COLUMN>
  80:  Matrix<T, ROW, COLUMN>::~Matrix()
  81:  {
  82:      if(pData)
  83:          delete []pData;
  84:      pData = NULL;
  85:  }
  86:  //拷贝构造
  87:  template<typename T, std::size_t ROW, std::size_t COLUMN>
  88:  Matrix<T, ROW, COLUMN>::Matrix(const Matrix<T>& m)
  89:  {
  90:      _ROW = m.getRow();
  91:      _COLUMN = m.getColumn();
  92:      pData = new T[_ROW*_COLUMN];
  93:      assert(pData);
  94:      memcpy(pData, m.pData, _ROW*_COLUMN*sizeof(T));
  95:  }
  96:  //重载下标操作符
  97:  //a[m][n], a[m] 首先调用此重载运算符, 返回指针 (pData + m*_COLUMN)
  98:  //然后进行正常的指针运算 (pData + m*_COLUMN)[n] 
  99:  template<typename T, std::size_t ROW, std::size_t COLUMN>
 100:  T* Matrix<T, ROW, COLUMN>::operator[](std::size_t m)
 101:  {
 102:      assert(m >= 0 && m < _ROW);
 103:      return (pData + m*_COLUMN);
 104:  }
 105:  //for const class
 106:  template<typename T, std::size_t ROW, std::size_t COLUMN>
 107:  const T* Matrix<T, ROW, COLUMN>::operator[](std::size_t m) const
 108:  {
 109:      assert(m >= 0 && m < _ROW);
 110:      return (pData + m*_COLUMN);
 111:      //return operator[](m);
 112:  }//*/
 113:  //a(m,n)
 114:  template<typename T, std::size_t ROW, std::size_t COLUMN>
 115:  T& Matrix<T, ROW, COLUMN>::operator()(std::size_t m, std::size_t n)
 116:  {   
 117:      assert(m < _ROW && m >= 0 && n < _COLUMN && n >= 0);          
 118:      return (pData + m*_COLUMN)[n]; 
 119:  }
 120:  //for const class
 121:  template<typename T, std::size_t ROW, std::size_t COLUMN>
 122:  const T& Matrix<T, ROW, COLUMN>::operator()
 123:          (std::size_t m, std::size_t n) const
 124:  {
 125:      assert(m < _ROW && m >= 0 && n < _COLUMN && n >= 0);          
 126:      return (pData + m*_COLUMN)[n]; 
 127:  }//*/
 128:   
 129:  //查看行列值
 130:  template<typename T, std::size_t ROW, std::size_t COLUMN>
 131:  const std::size_t Matrix<T, ROW, COLUMN>::getRow() const 
 132:  {
 133:      return _ROW;
 134:  }
 135:  template<typename T, std::size_t ROW, std::size_t COLUMN>
 136:  const std::size_t Matrix<T, ROW, COLUMN>::getColumn() const
 137:  {
 138:      return _COLUMN;
 139:  }
 140:   
 141:  //输出整个矩阵
 142:  template<typename T, std::size_t ROW, std::size_t COLUMN>
 143:  void Matrix<T, ROW, COLUMN>::displayMatrix() const
 144:  {
 145:      std::cout << std::endl << "Now The Matrix is: " << std::endl;
 146:      for(std::size_t i = 0; i < _ROW; i++)
 147:          for(std::size_t j = 0; j < _COLUMN; j++)
 148:          {
 149:              std::cout << *(pData+i*_COLUMN+j) << " ";
 150:              if(j == _COLUMN - 1)
 151:                  std::cout << std::endl;
 152:          }
 153:      std::cout << std::endl;
 154:  }
 155:  //重载 =
 156:  template<typename T, std::size_t ROW, std::size_t COLUMN>
 157:  Matrix<T>& Matrix<T, ROW, COLUMN>::operator=(const Matrix<T>& m)
 158:  {
 159:      if(this == &m)
 160:          return *this;
 161:      assert(_ROW == m.getRow() && _COLUMN == m.getColumn());
 162:      for(std::size_t i = 0; i < _ROW; i++)
 163:          for(std::size_t j = 0; j < _COLUMN; j++)
 164:          {
 165:              operator()(i, j) = m(i, j);    
 166:          }
 167:   
 168:      return *this;
 169:  }
 170:  //重载 +=
 171:  template<typename T, std::size_t ROW, std::size_t COLUMN>
 172:  Matrix<T>& Matrix<T, ROW, COLUMN>::operator+=(const Matrix<T>& m)
 173:  {
 174:      assert(_ROW == m.getRow() && _COLUMN == m.getColumn());
 175:      for(std::size_t i = 0; i < _ROW; i++)
 176:          for(std::size_t j = 0; j < _COLUMN; j++)
 177:          {
 178:              operator()(i, j) += m(i, j);    
 179:          }
 180:      return *this;
 181:  }
 182:  //operator+(const Matrix<T>& m)
 183:  template<typename T, std::size_t ROW, std::size_t COLUMN>
 184:  Matrix<T> Matrix<T, ROW, COLUMN>::operator+(const Matrix<T>& m)
 185:  {
 186:      assert(_ROW == m.getRow() && _COLUMN == m.getColumn());
 187:      Matrix<T, ROW, COLUMN> matrix;
 188:      for(std::size_t i = 0; i < _ROW; i++)
 189:          for(std::size_t j = 0; j < _COLUMN; j++)
 190:          {
 191:              matrix(i, j) = operator()(i, j) + m(i, j);    
 192:          }
 193:      return matrix;
 194:  }
 195:  //operator-()
 196:  template<typename T, std::size_t ROW, std::size_t COLUMN>
 197:  Matrix<T>& Matrix<T, ROW, COLUMN>::operator-()
 198:  {
 199:      for(std::size_t i = 0; i < _ROW; i++)
 200:          for(std::size_t j = 0; j < _COLUMN; j++)
 201:          {
 202:              operator()(i, j) =     -operator()(i, j);
 203:          }
 204:      return *this;
 205:  }
 206:  //operator*()
 207:  template<typename T, std::size_t ROW, std::size_t COLUMN>
 208:  Matrix<T> Matrix<T, ROW, COLUMN>::operator*(const Matrix<T>& m)
 209:  {
 210:      assert(_ROW == m.getRow() && _COLUMN == m.getColumn());
 211:      Matrix<T, ROW, COLUMN> matrix;
 212:      for(std::size_t i = 0; i < _ROW; i++)
 213:          for(std::size_t j = 0; j < _COLUMN; j++)
 214:          {
 215:              matrix(i, j) = operator()(i, j) * m(i, j);    
 216:          }
 217:      return matrix;
 218:  }
 219:  //矩阵转置 operator!()
 220:  template<typename T, std::size_t ROW, std::size_t COLUMN>
 221:  Matrix<T> Matrix<T, ROW, COLUMN>::operator!()
 222:  {
 223:      Matrix<T, ROW, COLUMN> matrix;
 224:      for(std::size_t i = 0; i < _ROW; i++)
 225:          for(std::size_t j = 0; j < _COLUMN; j++)
 226:          {
 227:              matrix(i, j) = (*this)(j, i);    
 228:          }
 229:      return matrix;
 230:  }
 231:   
 232:  //for cout << matrix;
 233:  template<typename T1>
 234:  std::ostream& operator<<(std::ostream& os, const Matrix<T1>& m)
 235:  {
 236:      if(m.getRow() <= 0 || m.getColumn() <= 0)
 237:          return os;
 238:      for(std::size_t i = 0; i < m.getRow(); i++)
 239:          for(std::size_t j = 0; j < m.getColumn(); j++)
 240:          {
 241:              os << m(i, j) << " ";
 242:              if(j == m.getColumn() - 1)
 243:                  os << std::endl;
 244:          }
 245:      return os;
 246:  }
 
   1:  //重载下标操作符, m[i][j], 方法2:
   2:  //使用代理类. 定义两个类,当第一个类调用重载的操作符时,使此函数返回
   3:  //第二个类的对象,在第二个类中,同样定义了运算符 [] 重载。但在第一个
   4:  //类中的重载操作符要能访问第二个类的私有成员,那么就应该把第一个类声明
   5:  //为第二个类的友元。
   6:  //----
   7:  //每个MatrixBody对象扮演的是一个一维数组,而这个一维数组没有在使用Matrixs的
   8:  //程序中出现。扮演其它对象的对象通常被称为代理类。在这个例子里,MatrixBody是
   9:  //一个代理类。它的实例扮演的是一个在概念上不存在的一维数组。
  10:  //代理类的概念见: More Effective C++ Item M30:代理类
  11:  #pragma once
  12:  #include <iostream>
  13:  #include <cstddef>
  14:  #include <cassert>
  15:   
  16:  template <typename T> 
  17:  class Matrixs
  18:  {
  19:      class MatrixBody
  20:      {
  21:          friend class Matrixs<T>;
  22:      private:
  23:          T* _pData;
  24:          std::size_t _Rows;
  25:          std::size_t _Column;
  26:          std::size_t _CurrentRow;     //当前行
  27:   
  28:          MatrixBody(std::size_t row, std::size_t column);
  29:   
  30:      public:
  31:          T& operator[](std::size_t j);
  32:          const T& operator[](std::size_t j) const;
  33:          ~MatrixBody();
  34:      }mBody;
  35:   
  36:  public:
  37:      Matrixs(std::size_t row, std::size_t column)
  38:          :mBody(row, column)
  39:      { }
  40:   
  41:   
  42:      //[] 返回第二个类的对象
  43:      MatrixBody& operator[](std::size_t i);
  44:      const MatrixBody& operator[](std::size_t i) const;
  45:   
  46:      //输出矩阵内容
  47:      void displayMatrix() const;
  48:   
  49:  };
  50:   
  51:  //代理类构造函数
  52:  template <typename T> 
  53:  Matrixs<T>::MatrixBody::MatrixBody(std::size_t row, std::size_t column)
  54:  {
  55:      _Rows   = row;
  56:      _Column = column;
  57:      _CurrentRow = -1;
  58:      _pData = new T[_Rows*_Column];
  59:      assert(_pData != NULL);
  60:      memset(_pData, 0, _Rows*_Column*sizeof(T));
  61:  }
  62:  //代理类的下标重载符
  63:  template <typename T> 
  64:  T& Matrixs<T>::MatrixBody::operator[](std::size_t j)
  65:  {
  66:      bool row_error = false;
  67:      bool column_error = false;
  68:      try
  69:      {
  70:          if(_CurrentRow < 0 || _CurrentRow >= _Rows)
  71:              row_error = true;
  72:          if(j < 0 || j >= _Column)
  73:              column_error = true;
  74:          if(row_error || column_error)
  75:              throw 'e';
  76:      }
  77:      catch(char)
  78:      {
  79:          if(row_error)
  80:              cerr << "Row access invalid!" << _CurrentRow << endl;
  81:          if(column_error)
  82:              cerr << "Column access invalid!" << j << endl;
  83:      }
  84:   
  85:      return _pData[_CurrentRow*_Column + j];
  86:  }
  87:   
  88:  //代理类析构函数
  89:  template <typename T> 
  90:  Matrixs<T>::MatrixBody::~MatrixBody()
  91:  {
  92:      if(_pData != NULL)
  93:          delete []_pData;
  94:      _pData = NULL;
  95:  }
  96:   
  97:  //矩阵类下标重载符[] //模板的语法实在是太奇怪了,注意下面必须有 typename
  98:  template<typename T>
  99:  typename Matrixs<T>::MatrixBody& Matrixs<T>::operator[](std::size_t i)
 100:  {
 101:      mBody._CurrentRow = i;
 102:      return mBody;
 103:  }
 104:   
 105:  template <typename T> 
 106:  const typename Matrixs<T>::MatrixBody& Matrixs<T>::operator[](std::size_t i) const
 107:  {
 108:      mBody._CurrentRow = i;
 109:      return mBody;
 110:      //operator[](i);
 111:  }
 112:   
 113:  //输出矩阵内容
 114:  template <typename T> 
 115:  void Matrixs<T>::displayMatrix() const
 116:  {
 117:      std::cout << std::endl << "Now The Matrix is: " << std::endl;
 118:      for(std::size_t i = 0; i < mBody._Rows; i++)
 119:      {
 120:          for(std::size_t j = 0; j < mBody._Column; j++)
 121:          {
 122:              std::cout << *(mBody._pData+i*mBody._Column+j) << " ";
 123:   
 124:              if(j == mBody._Column - 1)
 125:                  std::cout << std::endl;
 126:          }
 127:      }
 128:      std::cout << std::endl;
 129:  }
 
   1:  //test for Matrix class
   2:  #include "MatrixClass.h"
   3:  #include "MatrixClass1.h"
   4:  #include <iostream>
   5:   
   6:  int main()
   7:  {
   8:   
   9:      //指定矩阵大小
  10:      Matrix<int, 6, 5> matrix;
  11:      std::cout << "ROW = " << matrix.getRow() << " "
  12:              << "COLUMN = " << matrix.getColumn() << std::endl;
  13:      matrix.displayMatrix();
  14:      matrix[1][2] = 5;
  15:      std::cout << "matirx[1][2] = " << matrix[1][2] << std::endl;
  16:      matrix[5][4] = 6;
  17:      std::cout << "matirx[5][4] = " << matrix[5][4] << std::endl;
  18:      //matrix[6][4] = 3; //溢出
  19:      matrix.displayMatrix();
  20:      matrix(3, 3) = matrix[5][4];
  21:      matrix.displayMatrix();
  22:   
  23:      //采用默认构造参数,默认大小
  24:      Matrix<int> matrix1;
  25:      matrix.displayMatrix();
  26:      matrix1[3][4] = 5;
  27:      std::cout << "ROW = " << matrix1.getRow() << " "
  28:              << "COLUMN = " << matrix1.getColumn() << std::endl;
  29:      std::cout << "matirx1[3][4] = " << matrix1[3][4] << std::endl;
  30:      std::cout << "matirx1[3][3] = " << matrix1[3][3] << std::endl;
  31:      matrix1.displayMatrix();//*/
  32:   
  33:      //test for +=
  34:      Matrix<int> matrix2;
  35:      matrix2[3][4] = 2;
  36:      matrix2[1][4] = 3;
  37:      matrix2.displayMatrix();
  38:      std::cout << "Test for the operator+=(): ";
  39:      matrix2 += matrix1;     //*/
  40:      matrix2.displayMatrix();
  41:   
  42:      //test for operator-()
  43:      std::cout << "Test for operator-(): ";
  44:      -matrix2;
  45:      matrix2.displayMatrix();
  46:   
  47:      //test for opeartor+() and =
  48:      std::cout << "Test for operator+() and operator=(): ";
  49:      matrix1 = matrix2;
  50:      matrix1 = matrix1 + matrix2;
  51:      matrix1.displayMatrix();
  52:   
  53:      //test for opeartor!()
  54:      std::cout << "Test for operator!(): ";
  55:      matrix2 = !matrix1;
  56:      matrix2.displayMatrix();
  57:   
  58:      std::cout << "Test for cout << matrix : " << std::endl;;
  59:      std::cout << matrix2 << endl;
  60:   
  61:      //测试代理类
  62:      std::cout << "Test for the proxy class: ";
  63:      Matrixs<int> a(5,5);
  64:      a.displayMatrix();
  65:      a[2][1] = 3;
  66:      a.displayMatrix();
  67:   
  68:      return 0;
  69:  }
 

      使用 C++ 实现二维数组, 主要有如下不同的方法,程序中使用的是第一种:

    
    //不同的方法创建一个 m[3][5]
    //1):
    int* m1 = new int[3*5];
    delete []m1;
    //点:调用不够直观
    //优点:连续储存,n 可以不是已知

    //2):
    int (*m2)[5] = new int[3][5];
    delete []m2;
    //缺点:n 必须是已知
    //优点:调用直观,连续储存,程序简洁(经过测试,析构函数能正确调用)

    //3):
    int** m3 = new int*[3];
    for(int i = 0; i < 3; i++)
        m3[i] = new int[5];

    for(int i = 0; i < 3; i++)
        delete []m3[i];
    delete []m3;
    //缺点:非连续储存,程序烦琐,m3 为 A** 类型
    //优点:调用直观,n 可以不是已知

    //4):
    vector< vector<int> > m4;
    m4.resize(3);
    for(int i = 0; i < 5; i++)
        m4.resize(5);
    //缺点:非连续储存,调试不够方便,编译速度下降,程序膨胀(实际速度差别不大)
    //优点:调用直观,自动析构与释放内存,可以调用 stl 相关函数,动态增长
    
    //5):
    vector< vector<int> > m5;
    m5.resize(3*5);
    //方法 1, 4 的结合

    //6):  3) 的改进
    int** m6 = new int*[3];
    m6[0] = new int[3*5];
    for(int i = 1; i < 3; i++)
        m6[i] = m6[i-1] + 5;    
    //优点: 连续存储, n 可以不是已知, 析构方便

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值