搜索
简帛阁>技术文章>比较运算符的重载

比较运算符的重载

2. 比较运算符的重载

C#中有6个比较运算符,它们分为3对:

●== 和 !=

●> 和 <

●>= 和 <=

C#要求成对重载比较运算符。如果重载了==,也必须重载!=,否则会产生编译错误。另外,比较运算符必须返回bool类型的值。这是它们与算术运算符的根本区别。两个数相加或相减的结果,理论上取决于数的类型。而两个Vector的相乘会得到一个标量。另一个例子是.NET基类System.DateTime,两个DateTime实例相减,得到的结果不是DateTime,而是一个System.TimeSpan实例,但比较运算得到的如果不是bool类型的值,就没有任何意义。

注意:

在重载==和!=时,还应重载从System.Object中继承的Equals()和GetHashCode()方法,否则会产生一个编译警告。原因是Equals()方法应执行与==运算符相同的相等逻辑。

除了这些区别外,重载比较运算符所遵循的规则与算术运算符相同。但比较两个数并不像想象的那么简单,例如,如果比较两个对象引用,就是比较存储对象的内存地址。比较运算符很少进行这样的比较,所以必须编写运算符,比较对象的值,返回相应的布尔结果。下面给Vector结构重载==和!=运算符。首先是==的执行代码:

      public static bool operator = = (Vector lhs, Vector rhs)

      {

         if (lhs.x = = rhs.x && lhs.y = = rhs.y && lhs.z = = rhs.z)

            return true;

         else

            return false;

      }

这种方式仅根据矢量组成部分的值,来对它们进行等于比较。对于大多数结构,这就是我们希望的,但在某些情况下,可能需要仔细考虑等于的含义,例如,如果有嵌入的类,是应比较对同一个对象的引用(浅度比较),还是应比较对象的值是否相等(深度比较)?

注意:

不要通过调用从System.Object中继承的Equals()方法的实例版本,来重载比较运算符,如果这么做,在objA是null时计算(objA==objB),这会产生一个异常,因为.NET运行库会试图计算null.Equals(objB)。采用其他方法(重写Equals()方法,调用比较运算符)比较安全。

还需要重载运算符!=,采用的方式如下:

      public static bool operator != (Vector lhs, Vector rhs)

      {

      return ! (lhs == rhs);

      }

像往常一样,用一些测试代码检查重写方法的工作情况,这次定义3个Vector对象,并进行比较:

      static void Main()

      {

         Vector vect1, vect2, vect3;

         vect1 = new Vector(3.0, 3.0,–10.0);

         vect2 = new Vector(3.0, 3.0,–10.0);

         vect3 = new Vector(2.0, 3.0, 6.0);

         Console.WriteLine("vect1= =vect2 returns " + (vect1= =vect2));

         Console.WriteLine("vect1= =vect3 returns " + (vect1= =vect3));

         Console.WriteLine("vect2= =vect3 returns " + (vect2= =vect3));

         Console.WriteLine();

         Console.WriteLine("vect1!=vect2 returns " + (vect1!=vect2));

         Console.WriteLine("vect1!=vect3 returns " + (vect1!=vect3));

         Console.WriteLine("vect2!=vect3 returns " + (vect2!=vect3));

      }

编译这些代码(下载代码中的Vectors3.cs),会得到一个编译器警告,因为我们没有为Vector重写Equals(),对于本例,这是不重要的,所以忽略它。

csc Vectors3.cs

Microsoft (R) Visual C# 2005 Compiler version 8.00.50215.33

for Microsoft (R) Windows (R) Framework version 2.0.50215

Copyright (C) Microsoft Corporation 2001-2005. All rights reserved.

 

Vectors3.cs(5,11): warning CS0660: 'Wrox.ProCSharp.OOCSharp.Vector' defines

       operator = = or operator != but does not override Object.Equals(object o)

Vectors3.cs(5,11): warning CS0661: 'Wrox.ProCSharp.OOCSharp.Vector' defines

        operator = = or operator != but does not override Object.GetHashCode()

在命令行上运行该示例,生成如下结果:

Vectors3

vect1= =vect2 returns True

vect1= =vect3 returns False

vect2= =vect3 returns False

 

vect1!=vect2   returns False

vect1!=vect3    returns True

vect2!=vect3    returns True

3. 可以重载的运算符

并不是所有的运算符都可以重载。可以重载的运算符如表5-5所示。

表 5-5

类    别

运 算 符

限    制

算术二元运算符

+, *, /, –, %

算术一元运算符

+, –, ++, ––

按位二元运算符

&, |, ^, <<, >>

按位一元运算符

!, ~, true, false

true和false运算符必须成对重载

比较运算符

==, !=, >=, <, <=, >

必须成对重载

赋值运算符

+=,–=,*=,/=,>>=,<<=,%=

,&=,|=,^=

不能显式重载这些运算符,在重写单个运算符如+,–,%等时,它们会被隐式重写

索引运算符

[]

不能直接重载索引运算符。第2章介绍的索引器成员类型允许在类和结构上支持索引运算符

数据类型转换运算符

()

不能直接重载数据类型转换运算符。用户定义的数据类型转换(本章的后面介绍)允许定义定制的数据类型转换


C++为了增强代码可读性引入了运算重载运算重载是具有特殊函数名函数,也具有其返回值类型,函数名字以及参数列表,其返回值类型与参数列表与普通函数类似。函数名字为:关键字operator后面接
*coding:utf8*classVersionNum(object):版本号比较默认版本以“”分割,各位版本位数不超过3例一:23545895由“”分割版本,235、458、95都不能大于999如
由于对运算重载不是多么理解诶,于是就百度了一下,结果发现一个解释很有趣百度知道,分享看看。代码如下:回答:+*/这样运算重定义,比如你自定义了一个类a,然后你可以自己重载这些运算,比如
目录一、前言二、重载作用三、自定义列表一、前言运算重载:为运算定义方法所谓重载,就是赋予新含义同一个运算可以有不同功能二、重载作用让自定义实例像内建对象一样进行运算操作让程序简介易读对
01运算重载需求C++预定义运算,只能用于基本数据类型运算:整型、实型、字符型、逻辑型等等,且不能用于对象运算。但是我们有时候又很需要在对象之间能用运算,那么这时我们就要重载运算,使
classTime{private:inthours;intminutes;public:Time();Time(inth,intm0);voidAddMin(intm);voidAddHr(inth
C++中的流插入运算“>>”和流输出运算“>”运算进行了重载,那么具体是怎么实现?输入运算重载istreamoperator>>(istreamin,Aa){in>>
说明:输入输出运算重载必须为友元函数,并且必须有输入输出流返回值,固定格式为:friendistream&operator>>(istream&,重载类名&);friendostream&op
重载二元操作方法二元运算又称为双目运算,即需要2个操作数运算,例如+*/等。运算重载可以分为3种方式:类非静态成员函数、类友元函数、普通函数。例如有2个操作数a和b,二元运算?
include<iostream>usingnamespacestd;//运算递增重载classmyint{friendostreamoperator<<(ostreamc