nice-标准简单类型类

原创 2003年02月27日 09:06:00

nice-标准简单类型类

  我们都知道,有些类实际上是实现了某种特殊的类型,是对语言变量类型的扩展。如分数类,等级类等。这些类最终的实现目标是让使用者像使用语言原本就提供的标准类型一样的操作,甚至不必理睬其是类的事实。这种类的使用范围非常具有典型性,我称之为标准类型类nice类。C++Builder中的AnsiString 就是符合这种标准的SST类。
  我们来看一个nice类的定义,看看作为一个nice类至少需要实现什么。

一个SST类的例子
  在C++中没有提供分数数据类型,我们以类的形式来实现它,因为分数是一种数据类型,自然要实现成nice形式。

class Faction
{
private:
  //提供实际值的数据成员
  int _Numerator ; //分子
  int _Denominator ; //分母,注意不能为零

  int _MaxCommonDivisor(int a,int b); //最大公约数
  int _MinCommonMultiple(int a,int b); //最小公倍数
  void _Simple() ; //化简
  void CommonDenominator(const Fraction &OthFrac);//通分
public:
  Faction();
  Faction(int Numerator,int Denomonator);
  Faction(int Value);
  Faction(float Value);

  Fraction & operator= (const Fraction &FracValue);
  friend Fraction operator+(const Fraction &Frac1,const Fraction &Frac2);
  friend Fraction operator-(const Fraction &Frac1,const Fraction &Frac2);
  friend Fraction operator*(const Fraction &Frac1,const Fraction &Frac2);
  friend Fraction operator/(const Fraction &Frac1,const Fraction &Frac2);
  friend int operator >(const Fraction &Frac1,const Fraction &Frac2);
  friend int operator <(const Fraction &Frac1,const Fraction &Frac2);
  friend int operator >=(const Fraction &Frac1,const Fraction &Frac2);
  friend int operator <=(const Fraction &Frac1,const Fraction &Frac2);
  friend int operator ==(const Fraction &Frac1,const Fraction &Frac2);
  friend int operator !=(const Fraction &Frac1,const Fraction &Frac2);
};

  一般nice类都有一个或若干个用来存放实际值的数据成员,但显然不应该暴露它们,你有没有见过int.Value类似的形式呢。这就要求必须有不通过成员函数(操作符除外)或数据成员而能和其它类型数据直接交互,这可以通过操作符重载以及构造函数来实现类型转化。另外还有一些常用的操作符要也能想往常一样可以使用。
  从以上例子可以看出,nice类的存放实际值的数据总是放在private部分声明,以避免直接访问,所有的访问都是通过操作符函数进行。作为一个类型,显然必须能够实例化变量,赋初值,加减乘除及逻辑比较运算。

Faction类为什么会被设计成这样?
  我们先拿最常用的类型int来看看,一个类型一般如何使用,只要我们的nice类可以像使用int标识符一样使用,那就是我们的目标。
一、首先是声明:
  声明一个变量 int x;
  带初值声明变量 int x=1;
  要我们的nice类能同样的使用,显然须实现缺省构造函数(可以看实际情况,也可能不需要,但我们建议还是给实际值成员赋个初值)和赋值操作符。这里涉及到如何给新类型规定其常量形式,整形的常量形式为无小数点的数字字符,其又分为十进制形式,八进制形式,十六进制形式,这些皆是它的常量形式。作为分数的常量形式最容易想到是x/y的形式,然而因为其是一个合法的表达式,在传递值之前会进行运算,最后传递给分数类变量的却是已经除运算过的可能会因舍入而形成误差的整形结果。这不是我们想要的。在这里,暂且用加引号的方法避免形成表达式运算。那么如上整形的两种声明应用于分数:
  Faction x;
  Faction x="2/3"; 非有理数。或 Faction x=2 可除尽为整数; 或 Faction x=1.5; 可除尽为小数。
  这需要分数Faction类实现:
  1、缺省构造函数Faction::Faction();
  2、转换字符串型数据的构造函数Faction::Faction(const char * const);
  3、转换整形数据的构造函数Faction::Faction(int);
  4、转换浮点型数据的构造函数Faction::Faction(float),
  5、赋值运算符Faction::operator=(const Faction&)。
二、基本算数运算:
  假设x及y已经被声明为int型。
  x加y:x+y;
  x减y:x-y;
  x和y相乘:x*y;
  x除以y:x/y;
  分数类要能完全实现这些运算符,需要注意的是和其常量形式及可转换类型的运算。比如和整形的运算:
  Faction x;
  x+2; 或 2+x;
  这里对于参加运算的整形数的前后位置应该都可以使用,采用友元函数的方法来实现操作符重载:
  friend Fraction operator+(const Fraction&,const Fraction&);
  friend Fraction operator-(const Fraction&,const Fraction&);
  friend Fraction operator*(const Fraction&,const Fraction&);
  friend Fraction operator/(const Fraction&,const Fraction&);
三、逻辑比较运算符:
  大于>,小于<,等于==,不等于!=,大于等于>=,小于等于<=。
  这里也存在着算术运算符的常量形式使用位置的问题,自然也需要用友元的方法来实现,原理上节已经解释过,这里不再赘述。实现如下:
  friend int operator >(const Fraction &,const Fraction &);
  friend int operator <(const Fraction &,const Fraction &);
  friend int operator >=(const Fraction &,const Fraction &);
  friend int operator <=(const Fraction &,const Fraction &);
  friend int operator ==(const Fraction &,const Fraction &);
  friend int operator !=(const Fraction &,const Fraction &);
四、输出流:
  不管什么类型的数据,最终都必须输出。在C++中最常见的输出机制便是cout,分数类也要实现能在cout中输出:cout<   为了实现在流中输出,需要重载运算符<<。
  friend ostream& operator<<(const ostream& ,const Fraction&);
五、不需要实现的一些运算符:
  一些运算符对于整形数是有意义的,而对于分数则意义不大或根本没有意义,这类运算符可以不必实现。如++,--,+=,-=,*=,/=等。
  此外当然可以添加一些特有的方法,前提是只要满足上面的几点要求。这样,新的类型(SST类)的使用可以说和标准简单类型的使用完全一样。

nice类设计归纳
  经过上面的分数类的实现及分析,读者对nice类应该有了一个大致的了解。如果你还没有完全搞清楚,也不必着急,你可以回过头来仔细看几遍,最好去真正调试一番。相信很快就可以搞明白。
  总而言之,一个nice类一般应该具有如下的几个成员函数及友元函数:
  1、缺省构造函数。
  2、常量形式参数构造函数。
  3、其它类型参数构造函数,可以和新类型混合运算的类型。
  4、基本算术运算符函数,如:+,-,*,/,++,--等。
  5、基本逻辑运算符函数,如:==,!=,<,>,<=,>=。
  6、输入输出流运算符函数:>>,<<。
  当然,以上的需要也并不绝对,实现者可以按照具体的情况进行选择。

简单JAVA类

所有简单JAVA类的开发要求如下: 1.根据已有的要求定义类的名称——Person; 2.根据给出的提示编写相应的熟悉,但是所有的属性必须都使用private关键字进行封装; 3.封装之后的属性...
  • kepler08
  • kepler08
  • 2016年12月16日 09:10
  • 1257

Python学习笔记(六)—几个标准类型内建函数

比如说cmp(),str(),type(),repr()等等 cmp(a,b)比较a和b,根据比较的结果返回一个整数i。 当a 当a>b时返回i>0;(即1) 当a=b时返回0. repr(...
  • yang6464158
  • yang6464158
  • 2014年03月03日 19:49
  • 849

JAVA简单类型与对象类型(复杂类型)

Java中int和Integer的区别 Java各种数据类型详细介绍及其区别 基本类型,或者叫做内置类型,是JAVA中不同于类的特殊类型。 Java中的简单类型从概念上分为四种:实数、整数、...
  • qq861138181
  • qq861138181
  • 2017年02月07日 10:45
  • 1747

GUID类型

好吧,我承认我见识少,今天刚接触到的一个类型:1.一个GUID为一个128位的整数(16字节),在使用唯一标识符的情况下,你可以在所有计算机和网络之间使用这一整数。  2.GUID 的格式为“xxxx...
  • tuyingbazi
  • tuyingbazi
  • 2011年05月28日 16:46
  • 6208

python内建函数(build-in function)

python3.25内建函数:
  • first_wolf
  • first_wolf
  • 2013年12月16日 19:44
  • 998

通过DLL导出类指针来传递及使用对象

开发DLL是windows编程中经常用到的一种技术。d
  • dragonno1
  • dragonno1
  • 2014年04月07日 17:50
  • 1130

关于POJO类

以下内容为转载,出处已未知: POJO(Plain Old Java Object)这种叫法是Martin Fowler、Rebecca Parsons和Josh MacKenzie在2000年的一次...
  • huiguixian
  • huiguixian
  • 2011年01月09日 22:25
  • 5721

Android官方开发指南-常见的意图(Common Intents)

常见的意图(Common Intents) Intent允许你通过描述一个你想执行(如“查看地图”或“拍照”)的简单的action,在另一个应用程序中启动一个Activity。这种类型的In...
  • u013656135
  • u013656135
  • 2015年02月28日 16:58
  • 1048

C++12.1.4 类的前向声明、不完全类型类

简介 在一个给定的源文件中,一个类只能被定义一次,如果在多个文件中定义一个类,那么每个文件中的定义必须是完全相同的 将类定义放在头文件中,可以保证在每个使用类的文件中以同样的方式定义类。使用头文件保护...
  • hlsdbd1990
  • hlsdbd1990
  • 2015年06月18日 10:24
  • 1061

标准类型操作符和内建函数

标准类型操作符和内建函数 复数的属性(内建) int()、math.floor()和round()函数的比较     int()    函数直接截...
  • zhangzhuang1127
  • zhangzhuang1127
  • 2013年08月17日 13:16
  • 841
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:nice-标准简单类型类
举报原因:
原因补充:

(最多只允许输入30个字)