首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

用种模拟一个二维数组

2013-07-27 
用类模拟一个二维数组想设计一个类来模拟二维数组的行为,求大家给几个思路或代码。类二维数组[解决办法]内

用类模拟一个二维数组
想设计一个类来模拟二维数组的行为,求大家给几个思路或代码。 类 二维数组
[解决办法]
内存要连续, 又要支持 xx[2][3] 这种写法的话, 中间需要有个代理类.
[解决办法]
下面的代码中的row_accessor就是代理类,是为了实现ary[i][j]的访问方法。


class double_array_2d
{
public:
  //缺省构造函数,空数组
  double_array_2d()
    : data(0)
    , row_count(0)
    , col_count(0)
  {
  }
  //构造函数,创建一个crow行ccol列的二维数组
  double_array_2d( int crow, int ccol )
    : data( new double[ crow * ccol ] )
    , row_count( crow )
    , col_count( ccol )
  {
  }
  //拷贝构造函数,分配空间并复制数据
  double_array_2d ( double_array_2d const & src )
    : data( new src.row_count * src.col_count )
    , row_count( src.row_count )
    , col_count( src.col_count )
  {
    for( int i = 0; i < row_count * col_count; ++ i )
    {
       data[i] = src.data[i];
    }
  }
  //析构时释放空间。
  ~double_array_2d()
  {
    if( data )
    {
      delete []data;
    }
  }
  //普通的访问方法,调用者需要保证不越界,调试版本用断言检查
  double & at( unsigned int row, unsigned int col )
  {
     assert( row < row_count && col < col_count );
     return data[ row * col_count + col ];
  }
  //普通的访问方法,常量版本,调用者需要保证不越界,调试版本用断言检查
  double at( unsigned int row, unsigned int col )


  {
     assert( row < row_count && col < col_count );
     return data[ row * col_count + col ];
  }
   
  //下面实现operator[ ],也可以不实现,只用at进行访问。
  //这个类是辅助operator[ ]用的,因为operator[ ]只接收一个参数。
  class row_accessor
  {
  public:
     row_accessor( double * data, unsigned int length )
       : my_data(data)
       , my_length(length)
       {
       }
     double & operator[] ( unsigned int col ) throw()
     {
        assert( col < my_length );
        return data[ col ];
     }
     double operator[] ( unsigned int col ) const throw()
     {
        assert( col < my_length );
        return data[ col ];
     }
  };
   
  row_accessor operator[]( int row ) throw()
  {
     return row_accessor( data[ row ] );
  }
   
  const row_accessor operator[]( int row ) const throw()
  {
     return row_accessor( row );
  }
   
  //交换两个数组的数据
  //拷贝构造函数和redim通过调用这个方法实现。
  //这是除了构造与析构以外,唯一直接改变data、row_count与col_count的成员函数
  //其改变也是在两个构造完成的array之间进行交换,并且是长度与指针信息一同交换,
  //从而保证内存分配与释放的安全性
  void swap( double_array_2d & other ) throw()
  {
     unsigned int crow = row_count;
     unsigned int ccol = col_count;
     double * my_data = data;
     data = other.data;
     row_count = other.row_count;
     col_count = other.col_count;
     other.data = my_data;


     other.row_count = crow;
     other.col_count = ccol;
  }
  //重新分配,可以增加代码以保持数组中的数据,用构造函数+swap实现
  void redim( unsigned int crow, unsigned ccol )
  {
    double_array_2d temp( crow, ccol );
    //可以添加代码把data中的数据或一部分数据拷贝到temp中。
    //拷贝时要用二重循环,用at或operator[]访问数据
    temp.swap( * this );
  }
  //拷贝赋值操作符,用拷贝构造函数和swap实现
  double_array_2d & operator = ( double_array_2d const & other )
  {
    double_array_2d temp( other );
    temp.swap( * this );
  }
   
private:
  unsigned int row_count;
  unsigned int col_count;
  double * data;
private:
  //如果不想实现拷贝构造和拷贝赋值,可以用下面的代码禁止拷贝操作
  //这时前面的拷贝构造函数和拷贝赋值操作符的定义就不需要了
  //double_array_2d ( double_array_2d const & src );
  //double_array_2d & operator = ( double_array_2d const & other );
};


[解决办法]
其实更简单的方法是:



template<unsigned int L,typename T>
class array
{
    T data[L];
public:
    T & operator[] (unsigned int i )
    {
        return data[i];
    }
    T const & operator[] ( unsigned int i ) const
    {
         return data[i];
    }
};

然后:
int a[10][20]就是array<10, array<20, int> > a;
double b[10][3][2]就是array<10, array<3, array<2, double> > > b;
[解决办法]
1)vector< vector< T> > ;
2)自定义,需要定义 
array1 operator[](int n)const 和
array1 & operator[](int n);

这个array1,好看一点,用代理;
不好看的直接就是指针,连&也省略了。
内部用二级指针 T**;
a)  可以模仿的逼真点,像实际二维数组一样;
    那就只分配2次,一次分配1级指针,一次分配全部数据。


    和内置的二维数组的内存布局相同,可以当做内置二维数组用。 
b)  每个1级指针都分配数据内存,这个不太像,内置二维数组的内存布局;
    如果定义一个函数可以用于,内置二维数组的话
    一定不能用于这种方式模拟的数组,因为内存不连续。 
    好处是,可以适应内存碎片比较严重的情况,每次分配的内存要小得多

热点排行