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
- Debug日志:OOP版填充数字矩阵的一个失败反例
- MOOC清华《面向对象程序设计》第5章:OOP版填充数字旋转矩阵
- MOOC清华《面向对象程序设计》第5章:OOP版填充数字旋转矩阵-产品级!-终极中文版!
- MOOC清华《面向对象程序设计》第5章:OOP版填充数字矩阵(采用模板方法)
- MOOC清华《面向对象程序设计》第5章:OOP版填充数字矩阵-产品级终极中文版 v 2.0(增加按行、按列填充)
- java volatile的一个验证反例
- 填充一个上三角矩阵
- 矩阵的蛇形填充
- 一个失败的总结,日志分析
- 一个失败的总结,日志分析
- 做一个oop版的电子词典
- 矩阵填充的SVT算法
- 推荐一个查看debug日志的工具:webgrind
- Debug日志:一个关于“全局变量”的常见错误
- 填充矩阵
- 【面试题】剑指offer20--顺时针打印一个矩阵的数字
- 做一个oop版的电子词典(扩展1)
- 数字填充
- hdu 1530最大团模板
- LibreOJ Round #4 A.游戏
- level set 模型介绍
- python提取GIST特征,安装pyleargist包
- R语言在直方图上添加正太曲线与核密度曲线
- Debug日志:OOP版填充数字矩阵的一个失败反例
- 网易 彩色砖
- 关于JVM的面试总结
- Ubuntu下安装Cppcheck源码操作步骤
- 对于CAN ID的理解
- 再起航,我的学习笔记之JavaScript设计模式15(组合模式)
- FreeRDP的安装方法
- delphi通过函数名动态调用函数的方法(方便功能的扩展)
- 饿了么的架构设计及演进之路