//例子:旋转方阵填充,要求矩阵大小任意,尺寸在运行时输入 设计思路:从上到下 int main() { cout << "Please input N:"; int size; cin >> size; Matrix obj(size);//生成N*N矩阵 obj.fill(); cout <<obj; return 0; } 设计类的接口:设计Matrix的接口 class Matrix { public: Matrix(int size); void fill(); friend osream& operator<<(ostream& out,const Matrix& m); } 实现类的接口:确定成员变量 class Matrix { int _size;//方阵的规模 int *_data;//数据空间 public: Matrix(int size); ~Matrix(); void fill(); friend ostream& operator<<(ostream& out,const Matrix& m); }; 实现类的接口:实现构造函数,析构函数,和流输出操作符 Matrix::Matrix(int size):_size(size) { _data = new int[size * size]; memset(_data,0,sizeof(int)*_size*_size); } Matrix::~Matrix() { delete[] _data; } ostream& operator<<(ostream& out,const Matrix& m) { for(int r = 0; r < m._size; r++) for(int c = 0; c < m._size) cout << *(m + r * m._size + c) << ' '; cout << endl; } 如何实现填充的成员函数,将从1开始的数字以此存放在正确的位置? 怎么确定某个待填充的数字的位置? 细化:增加一个辅助函数来计算并填充 class Matrix { int findPosition();//新增的辅助函数 public: }; void Matrix::fill() { for(int num = 1; num <=_size * _size; num++) { int pos = findPosition(); _data[pos] = num; } } 进一步分析: 每一个数字都与上一个数字相邻(上下左右,根据上一个数字位置和当前运动方向,可以确定其位置) 所以需要存储上一个位置和当前的运动方向 class Matrix { int row,col; char dir; int findPosition(); public: }; 初始状态:初始方向为向下,那么在1之前,当前位置应该是在(-1,0) Matrix::Matrix(int size):_size(size),row(-1),col(0),dir('D') { _data = new int[size*size]; } 下一个位置:根据上一个位置和当前的方向来确定 int Matrix::findPosition() { switch(dir) { case 'D': if(row < _size-1 && _data[(row+1)*_size + col] == 0) row++; else { dir = 'R';//next direction col++; } break; case 'R': if(col < _size - 1 && _data[row*_size + col + 1] == 0) col++; else { dir = 'U';//next direction row--; } break; case 'U': if(row > 0 && _data[(row-1) * _size + col] == 0) row--; else { dir = 'L';//next direction col--; } break; case 'L': if(col > 0 && _data[row * _size + col - 1] == 0) col--; else { dir = 'D'; row++; } break; } return row * _size + col; } 对于Matrix类来说,如果需要多种方式填充矩阵只需要修改findPosition()这个成员函数就可以了; 但是每次都需要改变Matrix这个类吗?只有findPosition()需要改变,其他的都不需要改变,可以使用虚函数的方式: 多态的威力:使用虚函数,将findPosition()函数的实现推迟到子类中 class Matrix { virtual int findPosition() = 0; }; class ClockwiseMatrix:public Matrix { int row,col; char dir; public: int findPosition(); }; class RowFirstMatrix:public Matrix { int next;//initialize as 0 public: int findPosition() { return next++; } }; int main() { // matrix.fill(); } void matrix::fill() { for(int num = 1;num <= N*N; num++) { int pos = findPosition();//findPosition();可以调用不同的形式 _data[pos] = num; } }