Debug日志:OOP版填充数字矩阵的一个失败反例

来源:互联网 发布:ios 网络请求缓存 编辑:程序博客网 时间:2024/04/30 23:58

先看源代码:

//main.cpp    #include <iostream>    #include "Matrix.h"    using namespace std;             const int str_length = 7;//经测试,至少为7;印证了每个汉字占2个字节('\0'占一个字节)      int main() {        int size;          char style[str_length];        char key_point[str_length];     cout << "请输入矩阵的边长 N: ";        cin >> size;       cout << "请输入填充方式(顺时针、逆时针、行优先、列优先): ";        cin >> style;        cout << "请输入从哪一个角开始填充(左上角、左下角、右上角、右下角): ";        cin >> key_point;              Style obj(size);            obj.fill_style(style, key_point);  obj.findPosition(); obj.fill();     cout << obj;                return 0;    }  

//Matrix.h    #ifndef Matrix_h    #define Matrix_h        #include <iostream>    using namespace std;        class Matrix{         public:        int _size;//方阵的规模         int *_data;//数据空间        int row, col;        char dir;//用于顺时针、逆时针、行优先、列优先时的方向判定      char* _style;//填充方式(顺时针、逆时针、行优先、列优先)        char* _key_point;//填充关键点,根据情况赋值为四个角     Matrix(int size);        ~Matrix();       void fill();        virtual int findPosition() = 0;//关键一笔!用纯虚函数定义接口       friend ostream& operator<< (ostream& out, const Matrix& m);     };    class ClockwiseMatrix:public Matrix{public:using Matrix::Matrix;int findPosition();//顺时针辅助函数 };class AnticlockMatrix:public Matrix{public:using Matrix::Matrix;int findPosition();//逆时针辅助函数 };class RowFirstMatrix:public Matrix{public:using Matrix::Matrix;    int findPosition();//行优先辅助函数 };class ColFirstMatrix:public Matrix{public:using Matrix::Matrix;    int findPosition();//列优先辅助函数   };class Style:public Matrix{//Style不能继承Matrix,否则Style不能实例化对象,因为继承后Style也是抽象类//除非在Style中定义了继承来的Matrix中的纯虚函数,这样Style就不是抽象类了,//就可以实例化对象。同时测试表明:纯虚函数不能用= delete删除。 public:using Matrix::Matrix; void fill_style(char* str1, char* str2); int findPosition();//定义纯虚函数,让Style不是抽象类 ClockwiseMatrix Clockwise;//在一个类的成员函数中调用另一个类的成员函数,  AnticlockMatrix Anticlock;//除了继承这一方法以外,第二种方法就是类A中 RowFirstMatrix RowFirst;//定义类B的一个对象,然后在类A的成员函数中就可以  ColFirstMatrix ColFirst;//通过对象名加点运算符的方式调用类B的成员函数了。 };    #endif    

//Matrix.cpp    #include <iostream>    #include <cstring>    #include "Matrix.h"    using namespace std;        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++){ //row            for(int c = 0; c < m._size; c++) //col                cout << *(m._data + r * m._size + c) << '\t';            cout << endl;        }    }          void Matrix::fill(){         for(int num = 1; num <= _size * _size; num++){            int pos = findPosition();            _data[pos] = num;        }    }       

//Style.cpp#include <iostream>    #include <cstring>    #include "Matrix.h"    using namespace std;        void Style::fill_style(char* str1, char* str2){           _style = str1;        _key_point = str2;    }int Style::findPosition(){    if(strcmp(_style, "顺时针") == 0){     Clockwise._size = _size;        if(strcmp(_key_point, "左上角") == 0){        Clockwise.row = 0;            Clockwise.col = -1;            Clockwise.dir = 'R';         return Clockwise.findPosition();}            if(strcmp(_key_point, "右上角") == 0){        Clockwise.row = -1;            Clockwise.col = _size - 1;            Clockwise.dir = 'D';        return Clockwise.findPosition();}            if(strcmp(_key_point, "右下角") == 0){        Clockwise.row = _size - 1;            Clockwise.col = _size;            Clockwise.dir = 'L';         return Clockwise.findPosition();}            if(strcmp(_key_point, "左下角") == 0){        Clockwise.row = _size;            Clockwise.col = 0;            Clockwise.dir = 'U';        return Clockwise.findPosition();}    }            if(strcmp(_style, "逆时针") == 0){     Anticlock._size = _size;        if(strcmp(_key_point, "左上角") == 0){            Anticlock.row = -1;            Anticlock.col = 0;            Anticlock.dir = 'D';            return Anticlock.findPosition();}           if(strcmp(_key_point, "左下角") == 0){            Anticlock.row = _size - 1;            Anticlock.col = -1;            Anticlock.dir = 'R';  return Anticlock.findPosition(); }           if(strcmp(_key_point, "右下角") == 0){            Anticlock.row = _size;            Anticlock.col = _size - 1;            Anticlock.dir = 'U';  return Anticlock.findPosition(); }           if(strcmp(_key_point, "右上角") == 0){            Anticlock.row = 0;            Anticlock.col = _size;            Anticlock.dir = 'L';   return Anticlock.findPosition();}       }            if(strcmp(_style, "行优先") == 0){     RowFirst._size = _size;        if(strcmp(_key_point, "左上角") == 0){            RowFirst.row = 0;          RowFirst.col = -1;          RowFirst.dir = 'D';return RowFirst.findPosition();}         if(strcmp(_key_point, "右上角") == 0){            RowFirst.row = 0;          RowFirst.col = _size;          RowFirst.dir = 'L';  return RowFirst.findPosition(); }            if(strcmp(_key_point, "左下角") == 0){            RowFirst.row = _size - 1;          RowFirst.col = -1;  RowFirst.dir = 'R';   return RowFirst.findPosition();}          if(strcmp(_key_point, "右下角") == 0){            RowFirst.row = _size - 1;          RowFirst.col = _size;          RowFirst.dir = 'U';            return RowFirst.findPosition();}           }          if(strcmp(_style, "列优先") == 0){      ColFirst._size = _size;        if(strcmp(_key_point, "左上角") == 0){            ColFirst.row = -1;          ColFirst.col = 0;          ColFirst.dir = 'D';    return ColFirst.findPosition();}          if(strcmp(_key_point, "右上角") == 0){            ColFirst.row = -1;          ColFirst.col = _size - 1;          ColFirst.dir = 'L';           return ColFirst.findPosition();}          if(strcmp(_key_point, "左下角") == 0){            ColFirst.row = _size;          ColFirst.col = 0;          ColFirst.dir = 'R';  return ColFirst.findPosition();}         if(strcmp(_key_point, "右下角") == 0){            ColFirst.row = _size;          ColFirst.col = _size - 1;          ColFirst.dir = 'U';             return ColFirst.findPosition();}      } } 

//ClockwiseMatrix.cpp#include <iostream>       #include "Matrix.h"    using namespace std; int ClockwiseMatrix::findPosition(){      switch(dir){            case 'D':                if(row < _size - 1 && _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 = 'U'; // next direction                    row--;                }                break;            case 'U':                if(row > 0 && _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 = 'D'; // next direction                    row++;                }                break;        }        return row * _size + col;    }    

//AnticlockMatrix.cpp#include <iostream>       #include "Matrix.h"    using namespace std; int AnticlockMatrix::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'; // next direction                    row++;                }                break;        }        return row * _size + col;    }    

//RowFirstMatrix.cpp#include <iostream>       #include "Matrix.h"    using namespace std; int RowFirstMatrix::findPosition(){      switch(dir){          case 'D'://行优先且向右且向下填充(左上角)              if(col < _size - 1 && _data[row * _size + col + 1] == 0)                  col++;              else                  if(row < _size - 1){                      row++;                      col = 0;                  }              break;          case 'L'://行优先且向左且向下填充(右上角)              if(col > 0 && _data[row * _size + col - 1] == 0)                    col--;                else                  if(row < _size - 1){                      row++;                      col = _size - 1;                  }              break;          case 'R'://行优先且向右且向上填充(左下角)              if(col < _size - 1 && _data[row * _size + col + 1] == 0)                   col++;              else                  if(row > 0){                      row--;                      col = 0;                  }              break;          case 'U'://行优先且向左且向上填充(右下角)              if(col > 0 && _data[row * _size + col - 1] == 0)                    col--;               else                  if(row > 0){                      row--;                      col = _size - 1;                  }              break;      }      return row * _size + col;  }  

//ColFirstMatrix.cpp#include <iostream>       #include "Matrix.h"    using namespace std; int ColFirstMatrix::findPosition(){      switch(dir){          case 'D'://列优先且向下且向右填充(左上角)              if(row < _size - 1 && _data[(row + 1) * _size + col] == 0)                    row++;              else                  if(col < _size - 1){                      col++;                      row = 0;                  }              break;          case 'L'://列优先且向下且向左填充(右上角)              if(row < _size - 1 && _data[(row + 1) * _size + col] == 0)                    row++;                else                  if(col > 0){                      col--;                      row = 0;                  }              break;          case 'R'://列优先且向上且向右填充(左下角)              if(row > 0 && _data[(row - 1) * _size + col] == 0)                    row--;               else                  if(col < _size - 1){                      col++;                      row = _size - 1;                  }              break;          case 'U'://列优先且向上且向左填充(右下角)              if(row > 0 && _data[(row - 1) * _size + col] == 0)                    row--;              else                  if(col > 0){                      col--;                      row = _size - 1;                  }              break;      }      return row * _size + col;  }  

经验总结:

这个工程,编译器没有报错,测试结果却全盘错误。从中午十二点调试到现在晚上九点半。调试的心得和失败的原因如下。(我刚写在工程文件夹里的备忘录)

有些程序适合用结构化程序设计方法来做,或者结合一点面向对象的方法,但是过分地试图采用面向对象的技术,却会适得其反!chap5-001-2 的大段结构化程序、结合一点面向对象的方法,做得是多么好!而这个工程调了几乎一整天,依然像一团乱麻。造成混乱的中心问题是平级的派生类之间,参数不好传递,函数不好调用。同样是某个基类Base的派生类A1和A2,我用A1定义了对象,却需要用到A2中的成员函数;而A2的构造函数又需要从A1的对象得到初始化参数;而A1中开辟的内存空间却无法得到原本属于A2中的内存空间的数据。所以虽然没有语法错误,但是最终却输出的是大片为0的矩阵——因为调用的四个平级派生类的findPosition接口函数根本就没有把_data[]数组的值传递到main函数中定义对象所用的类Style的_data[]数组中来。这就像C语言中的goto语句一样混乱,像一团拎不清的意大利面条。

由此得到的经验就是:不要用一个派生类去调用平级的同源(派生自同一个基类)的派生类,否则就会造成上述混乱。应该结构化解决的问题,就直接结构化解决好了。

阅读全文
0 0
原创粉丝点击