//例子:旋转方阵填充,要求矩阵大小任意,尺寸在运行时输入
设计思路:从上到下
int main()
{
cout << "Please input N:";
int size;
cin >> size;
Matrix obj(size);//生成N*N矩阵
obj.fill();
cout <<obj;
return ;
} 设计类的接口:设计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,,sizeof(int)*_size*_size);
} Matrix::~Matrix()
{
delete[] _data;
} ostream& operator<<(ostream& out,const Matrix& m)
{
for(int r = ; r < m._size; r++)
for(int c = ; c < m._size)
cout << *(m + r * m._size + c) << '\t';
cout << endl;
} 如何实现填充的成员函数,将从1开始的数字以此存放在正确的位置?
怎么确定某个待填充的数字的位置? 细化:增加一个辅助函数来计算并填充
class Matrix
{
int findPosition();//新增的辅助函数
public:
}; void Matrix::fill()
{
for(int num = ; num <=_size * _size; num++)
{
int pos = findPosition();
_data[pos] = num;
}
}
进一步分析:
每一个数字都与上一个数字相邻(上下左右,根据上一个数字位置和当前运动方向,可以确定其位置)
所以需要存储上一个位置和当前的运动方向
class Matrix
{
int row,col;
char dir; int findPosition();
public:
};
初始状态:初始方向为向下,那么在1之前,当前位置应该是在(-,)
Matrix::Matrix(int size):_size(size),row(-),col(),dir('D')
{
_data = new int[size*size];
} 下一个位置:根据上一个位置和当前的方向来确定
int Matrix::findPosition()
{
switch(dir)
{
case 'D':
if(row < _size- && _data[(row+)*_size + col] == )
row++;
else
{
dir = 'R';//next direction
col++;
}
break;
case 'R':
if(col < _size - && _data[row*_size + col + ] == )
col++;
else
{
dir = 'U';//next direction
row--;
}
break;
case 'U':
if(row > && _data[(row-) * _size + col] == )
row--;
else
{
dir = 'L';//next direction
col--;
}
break;
case 'L':
if(col > && _data[row * _size + col - ] == )
col--;
else
{
dir = 'D';
row++;
}
break;
}
return row * _size + col;
} 对于Matrix类来说,如果需要多种方式填充矩阵只需要修改findPosition()这个成员函数就可以了;
但是每次都需要改变Matrix这个类吗?只有findPosition()需要改变,其他的都不需要改变,可以使用虚函数的方式:
多态的威力:使用虚函数,将findPosition()函数的实现推迟到子类中
class Matrix
{
virtual int findPosition() = ;
}; 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 = ;num <= N*N; num++)
{
int pos = findPosition();//findPosition();可以调用不同的形式
_data[pos] = num;
}
}

C++程序设计方法5:接口设计实例的更多相关文章

  1. 优秀的API接口设计原则及方法(转)

    一旦API发生变化,就可能对相关的调用者带来巨大的代价,用户需要排查所有调用的代码,需要调整所有与之相关的部分,这些工作对他们来说都是额外的.如果辛辛苦苦完成这些以后,还发现了相关的bug,那对用户的 ...

  2. STM32W108无线射频模块通用IO接口应用实例

    STM32W108无线射频模块通用IO接口应用实例 本实例编写STM32W108的GPIO測试程序,通过控制GPIO引脚,实现对LED灯的控制. 开发环境与硬件说明 硬件:STM32W108无线开发板 ...

  3. 《程序设计方法》【PDF】下载

    内容简介 <程序设计方法>主要以方法为主导,结合C语言,把程序设计方法学研究中若干成熟的理论和方法用通俗易懂的语言描述出来.<程序设计方法>还选取趣味性强.技巧性高.能够启发学 ...

  4. JAVAEE——Mybatis第一天:入门、jdbc存在的问题、架构介绍、入门程序、Dao的开发方法、接口的动态代理方式、SqlMapConfig.xml文件说明

    1. 学习计划 第一天: 1.Mybatis的介绍 2.Mybatis的入门 a) 使用jdbc操作数据库存在的问题 b) Mybatis的架构 c) Mybatis的入门程序 3.Dao的开发方法 ...

  5. php后台对接ios,安卓,API接口设计和实践完全攻略,涨薪必备技能

    2016年12月29日13:45:27    关于接口设计要说的东西很多,可能写一个系列都可以,vsd图都得画很多张,但是由于个人时间和精力有限,所有有些东西后面再补充   说道接口设计第一反应就是r ...

  6. C++ 11可变参数接口设计在模板编程中应用的一点点总结

    概述 本人对模板编程的应用并非很深,若要用一句话总结我个人对模板编程的理解,我想说的是:模板编程是对类定义的弱化. 如何理解“类定义的弱化”? 一个完整的类有如下几部分组成: 类的名称: 类的成员变量 ...

  7. DRF(2) - 解析器,序列化组件使用(GET/POST接口设计)

    一.DRF - 解析器 1.解析器的引出 我们知道,浏览器可以向django服务器发送json格式的数据,此时,django不会帮我们进行解析,只是将发送的原数据保存在request.body中,只有 ...

  8. Atitit.自定义存储引擎的接口设计 api 标准化 attilax 总结  mysql

    Atitit.自定义存储引擎的接口设计 api 标准化 attilax 总结  mysql 1. 图16.1:MySQL体系结构1 2. 16.7. 创建表create()虚拟函数:2 3. 16.8 ...

  9. Restful 2 --DRF解析器,序列化组件使用(GET/POST接口设计)

    一.DRF - 解析器 1.解析器的引出 我们知道,浏览器可以向django服务器发送json格式的数据,此时,django不会帮我们进行解析,只是将发送的原数据保存在request.body中,只有 ...

随机推荐

  1. Selenium+PhantomJS使用时报错原因及解决方案

    问题 今天在使用selenium+PhantomJS动态抓取网页时,出现如下报错信息: UserWarning: Selenium support for PhantomJS has been dep ...

  2. Aws云服务EMR使用

    Aws云服务EMR使用 创建表结构 创建abc库下的abc_user_i表字段s3://abc-server/abc-emr/shell/ABC_USER_HIVE.q: EXTERNAL 指定为外部 ...

  3. exec函数族

    进程程序替换 进程程序替换原理 fork创建子进程执行的是和父进程相同的程序(也有可能是某个分支),通常fork出的子进程是为了完成父进程所分配的任务,所以子进程通常会调用一种exec函数(六种中的任 ...

  4. MyBatis - 4.动态SQL

    动态 SQL是MyBatis强大特性之一.极大的简化我们拼装SQL的操作. 动态 SQL 元素和使用 JSTL 或其他类似基于 XML 的文本处理器相似. MyBatis 采用功能强大的基于 OGNL ...

  5. webpack学习笔记--区分环境

    为什么需要区分环境 在开发网页的时候,一般都会有多套运行环境,例如: 在开发过程中方便开发调试的环境. 发布到线上给用户使用的运行环境. 这两套不同的环境虽然都是由同一套源代码编译而来,但是代码内容却 ...

  6. Linux查找当前目录5天的文件并打包

    find . -name "*.sh" -mtime -5 |xargs tar zcvf /tmp/log.tar.gz 解释: *.sh是查找以.sh结尾的文件,也可以是其他如 ...

  7. POJ 2914 Minimum Cut【最小割 Stoer-Wangner】

    题意:求全局最小割 不能用网络流求最小割,枚举举汇点要O(n),最短增广路最大流算法求最大流是O(n2m)复杂度,在复杂网络中O(m)=O(n2),算法总复杂度就是O(n5):就算你用其他求最大流的算 ...

  8. 【NPM】常见问题解决

    问题列表 问题一:npm install 执行报错 npm ERR! Unexpected end of JSON input while parsing near '...ependencies&q ...

  9. docker-java Docker的java API

    docker-java docker-java 是 Docker的 Java 版本API Docker 当前的实现基于 Jersey 2.x 因此 classpath 不兼容老版本的 Jersey 1 ...

  10. plink命令

    用plink远程登陆link主机执行脚本,但是无法执行sudo命令 完成后自己关闭 plink   -l  root   192.168.1.21  df -h plink.exe  -ssh  -p ...