C++程序设计方法5:接口设计实例

//例子:旋转方阵填充,要求矩阵大小任意,尺寸在运行时输入
设计思路:从上到下
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) << '\t';
    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;
    }
}

原文链接: https://www.cnblogs.com/hujianglang/p/6697071.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/252404

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月14日 上午6:01
下一篇 2023年2月14日 上午6:01

相关推荐