DEVC++(1)单文件实现重载运算符的十六进制数类
本文运用DEVC++软件,通过C++类的定义和重载运算符来实现十六进制数类的运算操作,代码以单文件的方式来构建。
题目描述如下:
设计1~4位的无符号十六进制数据类class HEX. 可以创建如 ABCD、1234、DF09、AB、26之类的1~4位的十六进制的正整数。可以输入输出十六进制数据,可以实现十六进制数据和十进制数据的互换,可以实现2个十六进制数据的+、-、*、/、%操作。
为实现上述目的,我们首先来构建主函数,在主函数的构建中,我们自然希望操作界面简洁友好,希望将十进制数的加减乘除操作自然而然的转移到十六进制数上,使输入输出一目了然,因而在后续的类的定义上要下一番功夫,也要用到运算符的重载。
int main()
{ HEX n1,n2,n3;char repeat('Y');do{ n1 = 0; n2 = 0; n3 =0;cin>>n1>>n2; //n1,n2为十六进制数n3 = n1+n2;cout<<n1<<'+'<<n2<<'='<<n3<<endl;n3 = n1-n2;cout<<n1<<'-'<<n2<<'='<<n3<<endl;n3 = n1*n2;cout<<n1<<'*'<<n2<<'='<<n3<<endl;n3 = n1/n2;cout<<n1<<'/'<<n2<<'='<<n3<<endl;n3 = n1%n2;cout<<n1<<'%'<<n2<<'='<<n3<<endl;cout<<"Repeat?(Y/N)";cin>>repeat;}while(repeat=='Y'||repeat=='y');return 0;
}
由上面的主函数代码可以看到,加减乘除的命令符号沿用了十进制数的加减乘除,因而要对这些运算符在十六进制数类的范围下重载。此外,主函数设置了循环,只是为了方便重复测试。
下面来定义十六进制数类以及类的各种操作。特别要注意的一点是,因为在输入输出十六进制数时要访问类的成员,因而要在重载输入输出符时将其设置为友元。
#include <iostream>
#include <string>
#include <cmath>
#include <process.h>
using namespace std;
char Hex_num[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; //十六进制数字符的取值范围,便于后续的转化操作
class HEX
{ char m_num[10]; //可以存放10位十六进制数据,这样可以确保2个4位十六进制数据+和*的结果不会溢出
public:HEX(); //构造函数,初始化成全‘0’HEX(unsigned n); //用无符号整数创建十六进制数据,(即无符号整数转换成十六进制数据)unsigned GetBit(int i); //获得每一位数据的十进制数值operator unsigned(); //把十六进制数据转换成无符号的十进制数据int length(); //获得数据的长度HEX operator+(HEX n); //加法HEX operator-(HEX n); //减法运算要求被减数不小于减数HEX operator*(HEX n); //乘法HEX operator/(HEX n); //整除,即只要得到商HEX operator%(HEX n); //取模,即只要得到余数HEX& operator++(); //前置++HEX operator++(int); //后置++friend istream & operator>>(istream &i, HEX& n); // 输入十六进制数friend ostream & operator<<(ostream &o, HEX n);//输出十六进制数
};
上面只是类的申明,尤其是对运算只给出了一个基本框架,还须具体实现它,接下来就是对其的具体补充。
(1)默认构造函数
HEX::HEX()
{ memset(m_num,'0',sizeof(m_num));
}
(2) 重载构造函数,将十进制数转成十六进制数并以逆序存储
HEX::HEX(unsigned n) //十六进制数字符以逆序存储,并以'\0'字符结束
{ HEX();int i=0,t,j=0;if(n>0) //处理n>0的情况 while (n >0){t=n%16; m_num[i++]= Hex_num[t];n = n / 16;}else m_num[i++]='0'; //处理n=0的情况 m_num[i]='\0';
}
(3)获取每一位字符的十进制数值。主要思路,对读取的字符分两种情况处理,一种是A~F,一种是0~9,用其与A或0字符将字符转成数值,再根据所在位数(k),用 a×16k a\times 16^k作为返回结果。
unsigned HEX::GetBit(int i) //从十六进制数的最低位算起,获取第i位数的十进制表示
{ int a;if(m_num[i-1]>='A'&&m_num[i-1]<='F')a=m_num[i-1]-'A'+10;else a=m_num[i-1]-'0';while(i>1){a=a*16;i--;}return a;
}
(4)利用GetBit(i)实现把十六进制数据转换成无符号的十进制数据
HEX::operator unsigned()
{ int j=1;int b=0;for(;j<=10&&m_num[j-1]!='\0';j++) //判断字符是否结束b+=GetBit(j); return b;
}
(5)获得十六进制数的长度
int HEX::length()
{ return strlen(m_num);}
(6)重载‘+’运算符。对加减乘除运算符的重载主要是通过当前指针this和类型转换来实现的,即首先定义两个无符号整数变量a,b,然后通过类型转换将十六进制数转成十进制数,随后进行加减乘除运算,最后再通过调用构造函数把结果的数据类型转成十六进制。
这里之所以能够实现类型转换是因为前面定义了类型转换(4)HEX:: operator unsigned.
HEX HEX::operator+(HEX n) //利用类型转换实现四则运算
{ unsigned a,b;a=*this;b=n;return HEX(a+b);
}
(7)‘-’运算符重载。想法与加法运算符重载基本一致,但是需要注意的是要先判断被减数是否大于减数,若大于则进行减法运算,反之报错。
HEX HEX::operator-(HEX n)
{ unsigned a,b;a=*this;b=n;if(a<b)cout<<"错误:被减数小于减数"<<endl;else return HEX(a-b);
}
(8)‘*’,’/’,’%’运算符重载是平凡的,与加法是完全一致的,因而此处略去代码。
(9)实现前置++。想法是通过类型转换和this指针来实现。
HEX& HEX::operator++()
{ unsigned a=*this;*this=HEX(a+1);return (*this);
}
(10)实现后置++
HEX HEX::operator++(int)
{ HEX old=*this;++(*this);return old;
}
(11)实现十六进制数的输入。由于十六进制数以逆序存储,所以输入数据时对其反转,并以’\0’字符结束 。
istream& operator>>(istream& i, HEX& n)
{ cout<<"Please input a Hex number(>=0,<=FFFF,Hex characters:0-9 or A-F):"<<endl;char temp[10];i>>temp;int len=strlen(temp); //调用取长函数来寻找初始存储位置int j;for(j=0;j<len;j++)n.m_num[j]=temp[len-1-j];n.m_num[j]='\0';return i;
}
(12)实现十六进制数的输出。与输入类似,由于十六进制数以逆序存储,所以输出数据逆序输出。
ostream& operator<<(ostream& o, HEX n)
{ int len=n.length();int j;for(j=0;j<len;j++)o<<n.m_num[len-j-1];return o;
}
结语:
到这里就结束啦,回顾一下,其实通过重载运算符实现十六进制数的运算的关键在于运用类型转换和this指针,还有就是要清楚自己所定义的十六进制数在计算机中存储的方式,本文采用的逆序存储,其实也可以采用顺序存储啦,只要自己清楚其存储方式,在用字符的时候不要搞错了就好啦。
完整的代码我也会上传供大家参考,这个是单文件的,后续会补一个多文件的。
http://download.csdn.net/detail/zhazhazl/9645690
代码的测试输出如下:
DEVC++(1)单文件实现重载运算符的十六进制数类相关推荐
- JAVA 没有重载运算符,那么 String 类型的加法是怎么实现的,以及String类型不可变的原因和好处...
1, JAVA 不具备 C++ 和 C# 一样的重载运算符 来实现类与类之间相互计算 的功能 这其实一定程度上让编程失去了代码的灵活性, 但是个人认为,这在一定程度上减少了代码异常的概率 ...
- C++ Primer 5th笔记(chap 14 重载运算和类型转换)函数匹配与重载运算符
如果一个类既提供了转换目标是算术类型的类型转换,也提供了重载的运算符,则将会遇到重载运算符与内置运算符的二义性问题. 如果a是一种类型,表达式 a sym b 可能是: //不能通过调用形式来区分当前 ...
- c++的构造函数赋值函数重载运算符等
文章目录 一.前言 二.正文 1.拷贝构造函数 2.赋值函数 3.operator()() 重载()运算符 4.类中方法前面的template 5.类实例化的方式 (1)调用构造函数实例化和指针实例化 ...
- c++重载运算符实现分数加减乘除
实现结果如下图所示: 代码如下所示: #include <iostream>using namespace std;class Rational { public:Rational ope ...
- 【C++ 语言】面向对象 ( 函数重载 | 运算符重载 | 运算符重载两种定义方式 | 拷贝构造方法 | RVO 优化 | NRVO 优化 )
文章目录 函数重载 运算符重载 ( 类内部定义云算符重载 ) 运算符重载 ( 类外部定义运算符重载 ) 可重载的运算符 拷贝构造方法 编译器优化 ( RVO 优化 | NRVO 优化 ) 完整代码示例 ...
- C++ operator重载运算符详解
[toc] Chapter XIV C++ operator 重载运算符的作用: 主要是代替成员函数的方式为自建类型完成基本任务 当然, 用成员函数完全可以代替operator的功能, 但是使用起来绝 ...
- C++ 重载运算符简单举例
我们可以重定义或重载大部分 C++ 内置的运算符.这样,就能使用自定义类型的运算符. 重载的运算符是带有特殊名称的函数,函数名是由关键字 operator 和其后要重载的运算符符号构成的.与其他函数一 ...
- 中双目运算符_C++日志(四十)教你如何以非成员函数的形式重载运算符
上一篇日志中讲述了如何通过类的非静态函数成员,进行运算符重载: 机器学习入坑者:C++日志(三十九)教你如何以类的非静态成员函数形式重载运算符zhuanlan.zhihu.com 在C++中,同样可 ...
- Vue.js 单文件组件
单文件组件 介绍 在很多 Vue 项目中,我们使用 Vue.component 来定义全局组件,紧接着用 new Vue({ el: '#container '}) 在每个页面内指定一个容器元素. 这 ...
最新文章
- Jsoup 替换文本中所有的img src属性
- 为什么选择Java?Java具体好在哪?
- 基于MVC的网站和在线教育系统
- Mysql中慢查询Sql的记录查看
- Android Studio 创建不同分辨率的图标
- Centos 解压软件
- LINUX如何创建一个程序组
- ddos发包php文件,简单防范PHPDDOS对外发UDP包消耗流量
- DroidCamX – 让您的 Android 安卓手机瞬间变成电脑的高清无线摄像头
- win10教育版加域提示错误
- 安装CentOS找不到硬盘,无法分区,No disks selected
- haproxy编译安装以及配置文档介绍
- 3到5年工作经验是如何回答面试中被问到的Java集合框架问题
- 圆形谷仓Circular Barn_Silver---(DP优化 / )队列 + 贪心(复杂度O(2n))---DD(XYX)​​​​​​​的博客
- Infinite-former:无限记忆变换器
- 发烧后的咽喉肿痛自我治疗
- Cool Edit之生成.pk文件问题
- UITableView上下滚动卡顿(获取网络数据,下载图片之后)
- 红警ol总是服务器满 可服务区显示流程,红警OL:11月27日部分服务器数据互通合服公告...
- 工业3d相机选型指南(新手向)
热门文章
- 蓝桥杯嵌入式第七届省赛——“模拟液位检测告警系统”旧板标准库
- python time 模块函数
- 微信小程序相关面试题
- python 工厂函数
- [趋向指标] 主力买卖线
- 计算机应用研究 相对好发一些,传感技术学报期刊好投吗_机械科学与技术录用率高吗_计算机工程与应用被拒还能再投吗...
- that girl计算机音乐,最近很火的英文歌《That girl》原版,好听到爆!
- 单片机能代替PLC吗?过来人告诉你
- 行车记录仪软件测试报告工作表,车载终端设备行驶记录仪794-2019检测报告测试项目...
- 点击radio后面的文字勾选框选中