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

先看源代码:

//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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值