zoukankan      html  css  js  c++  java
  • 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) << '	';
        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之前,当前位置应该是在(-10)
    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;
        }
    }
    怕什么真理无穷,进一寸有一寸的欢喜。---胡适
  • 相关阅读:
    解决问题方法论
    mac os x命令行查找文件
    Ubuntu 更改文件夹权限及chmod详细用法
    Unable to mount the CD/DVD image virtualbox解决方法
    macbook air电池保养方法
    安装mac os x时about a second remaining解决方法
    No qualifying bean of type 'org.springframework.scheduling.TaskScheduler' available
    java.sql.SQLException: The server time zone value '�й���׼ʱ��' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver
    java.sql.SQLException: Access denied for user 'root'@'localhost' (using password: YES)解决方案
    使用springboot和easypoi进行的数据导出的小案例
  • 原文地址:https://www.cnblogs.com/hujianglang/p/6697071.html
Copyright © 2011-2022 走看看