已阅读5页,还剩25页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
运算符重载,运算符重载,运算符重载允许为运算指定用户定义的运算符实现,其中一个或两个操作数是用户定义的类或结构类型 所有一元和二元运算符都具有可自动用于任何表达式的预定义实现,可通过在类或结构中设置 operator 声明来引入用户定义的实现,其优先级总是高于预定义运算符实现 重载运算符便于程序员编写同时含有ADT和原生基本类型的中缀表达式,使程序更短,结构更清晰,复数类的四则运算,定义一个复数类Complex,将其多个实例进行四则运算,如何编程实现?,static void Main() Complex c1 = new Complex(1, 2); Complex c2 = new Complex(3.5, -2); Complex c3 = new Complex(-4, 23); /result=c1+c2-c3如何得到? Complex result = c1.Add(c2).Sub(c3); /将Add、Sub改成静态方法会不会更好些? Complex result2 = Complex.Sub(Complex.Add(c1, c2), c3); Console.WriteLine(result2.Print(); Console.Read(); ,在实现了需要的功能后,有没有一种让用户用更习惯、可读性、可编程性更好的方法来进行类似的运算呢? 解决方案:运算符重载!,可重载的运算符,一元运算符 + - ! + - true false 二元运算符 + - * / % & | = != = =,public class Complex public int real; public int imaginary; public Complex() public Complex(int real, int imaginary) this.real = real; this.imaginary = imaginary; public static Complex operator +(Complex c1, Complex c2) return new Complex(c1.real+c2.real, c1.imaginary +c2.imaginary); public static Complex operator -(Complex c1, Complex c2) return new Complex(c1.real-c2.real, c1.imaginary -c2.imaginary); public override string ToString() return(String.Format(“0 + 1i“, real, imaginary); ,二元运算符重载示例,注意函数原形!,public static void Main() Complex num1 = new Complex(3, 4); Complex num2 = new Complex(3, 4); Complex num3 = new Complex(-3, 4); Complex sum = num1.Add(num2); Complex result = num1 + num2 - num3; Console.WriteLine(“First complex number: 0“, num1); Console.WriteLine(“Second complex number: 0“, num2); Console.WriteLine(“The sum of the two numbers: 0“, sum); Console.WriteLine(“The result: 0“, result); Console.WriteLine(num1=num2); Console.Read(); ,自动调用num1的ToString(),默认=是比较两个对象的引用是否相同,public static bool operator =(Complex c1, Complex c2) if (c1.real = c2.real ,对=重载一定要对!=也进行重载,否则编译器报错,重写Equals和GetHashCode方法,警告1:“ConsoleApplication3.Complex”定义运算符 = 或运算符 !=,但不重写 Object.Equals(object o)和GetHashCode方法 对于引用类型来说,Object.Equals方法默认比较的是对象的相等性。当引用指向同一个对象的时候,它们是相等的,具有相同状态但指向不同对象的引用是不相等的,可对其进行改写,比较其内容是否相同 对于值类型来说,Equals已经重写过以进行值的比较,GetHashCode,重载Equals必须重载GetHashCode 这是一条编译器的rule。如果你重载了Equals不重载GetHashCode,编译器会发出警报 GetHashCode需要返回一个Int32值,这个值的规律很简单: 如果两个对象相同,则对象返回的HashCode必须相同。 如果两个对象返回的HashCode不相同,则这两个对象必定不相同。 两个对象不相同,不能保证hashCode不同 这样就使得Equals的效率提高很多。因为GetHashCode通常成本比Equals小得多。,public static bool operator =(Complex c1, Complex c2) if (c1.real = c2.real ,整理一下,这样更好,public override bool Equals(object obj) if(!(obj is Complex) return false; return this=(Complex)obj; public static bool operator =(Complex c1, Complex c2) return c1.Equals(c2); public static bool operator !=(Complex c1, Complex c2) return !c1.Equals(c2); public override int GetHashCode() return this.ToString().GetHashCode(); ,思考,如何实现复数的其他运算? 加/减 乘/除 取反 显示,自定义类型转换,现在,如果要实现int+Complex怎么办呢? 还有,complex+int Complex+double double+complex float+Complex Complex+float。 为每种运算定义重载太麻烦了,有更好的办法自定义类型转换,用户自定义变换,在不希望进行隐式类型变换或者表达式不合法时,有必要对表达式进行用户自定义的类型变换。 C#支持将用户自定义的ADT和内建的数据类型进行集成 C#使用关键字implicit和explicit来修改单参数的静态方法,用户自定义的隐式变换,Implicit关键字 用于声明用户定义的隐式类型转换运算符,可通过消除不必要的类型转换来提高源代码的可读 class MyType public static implicit operator int(MyType m) / code to convert from MyType to int ,MyType x; int i = x; / implicitly call MyTypes MyType-to-int conversion operator,用户自定义的显式变换,explicit 关键字 用于声明用户定义的显式类型转换运算符 class MyType public static explicit operator MyType(int i) / code to convert from int to MyType ,int i; MyType x = (MyType)i; / int-to-MyType requires cast,为Complex类添加自定义类型转换,Complex num1 = new Complex(2, 3); Complex num2 = new Complex(3, 4); Complex num3 = 4.5; Complex sum = num1 + 3 + num2; Console.WriteLine(“The sum of the 3 numbers: 0“, sum);,/ / 从实数到复数的自定义隐式转换 / / 复数的实部 / public static implicit operator Complex(double r) return new Complex(r, 0); ,两次隐式转换: 1)int-double 2)double-Complex,implicit改成explicit将会如何?,显式自定义类型转换,public static explicit operator Complex(double r) return new Complex(r, 0); public static void Main() Complex num1 = new Complex(2, 3); Complex num2 = new Complex(3, 4); Complex num3 = (Complex)4.5; Complex sum = num1 + (Complex)3 + num2; Console.WriteLine(“The sum of the 3 numbers: 0“, sum); ,更多运算符重载的例子。,public class DoubOp public DoubOp(int i,int j) x=i; y=j; public static DoubOp operator +(DoubOp a) a.x+; a.y+; return a; public static DoubOp operator -(DoubOp a) a.x-; a.y-; return a; public void Print() Console.WriteLine(this.x+“ “+this.y); int x,y; ,class Test public static void Main() DoubOp a=new DoubOp(10,29); a.Print(); a+; a.Print(); a-; a.Print(); ,一元运算符重载示例,书中重载示例:分数,class Fraction int numerator; int denominator; public Fraction(int numerator, int denominator) this.numerator = numerator; this.denominator = denominator; public static Fraction operator +(Fraction lhs, Fraction rhs) if (lhs.denominator = rhs.denominator) return new Fraction(lhs.numerator + rhs.numerator, lhs.denominator); else int firstProduct = lhs.numerator * rhs.denominator; int secondProduct = rhs.numerator * lhs.denominator; int newDenominator = lhs.denominator * rhs.denominator; return new Fraction(firstProduct + secondProduct, newDenominator).Simply(); public override string ToString() return string.Format(“0/1“, this.numerator, this.denominator); ,/ 对分数进行约简 public Fraction Simply() int num = Math.Abs(this.denominator); /从大到小查找分子分母的最大公约数 while (num 1) if (numerator % num = 0 ,public static bool operator =(Fraction lhs, Fraction rhs) Fraction f1 = lhs.Simply(); Fraction f2 = rhs.Simply(); if (f1.numerator = f2.numerator /更好的做法:交叉相乘若想等就相同 ,进一步:怎么比较分数的大小,思路 方法一:先进行通分,在分母相同的情况下,由分子比较来得到分数的大小 方法二:将2个分数都转换成double,然后比较double值 注意 重载了必须同时重载=必须同时重载=,分数-double并比较,public static implicit operator double(Fraction f) return (double)(f.numerator) / f.denominator; public static bool operator (Fraction lhs, Fraction rhs) double l = lhs; double r = rhs; return l r; ,/测试代码 double r = f3 + 3; Console.WriteLine(“0+3=1“, f3, r); Console.WriteLine(“0 is greater than 1 is 2 “, f1, f2, f1 f2);,编译器还会要求你添加的重载,更进一步问题,问题一: f23结果是什么?中间如何转换 问题二:如何实现下列这些操作? double+Fraction-Fraction Fraction+double -Fraction,显式类型变换,/测试代码 Fraction f5 = (Fraction)3.5 + f4; Co
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026区块链行业市场深度调研及发展趋势与投资战略研究报告
- 2026中国洗涤剂行业市场发展现状及环保洗涤和行业投资机会研究报告
- 2026中国隐私计算技术在金融风控中的应用模式与合规性框架构建报告
- 《城市卫生数字化管理操作手册》
- 冶金专科学校测试题及答案解析
- 农业科技推广与应用手册
- 2026年护士资格考试统考历年真题及答案
- 垃圾处理技术与环保政策手册
- 2025年农商行招聘考试真题及答案解析
- 农业农业大数据应用服务手册
- 高考化学复习:高中化学方程式
- 10J113-1内隔墙-轻质条板(一)
- 昆山市新初一分班语文试卷含答案
- 麻醉不良事件上报流程
- 全民健康养生餐饮连锁店项目策划书
- 超声引导下椎管内麻醉
- 建筑消防设施维护保养报告
- 传播研究方法与论文写作对文章的观察
- 皮类药材栽培技术-肉桂栽培(药用植物栽培技术课件)
- 高考日语基础归纳总结与练习(一轮复习)
- 2022年江苏苏州昆山市委老干部局招聘编外工作人员笔试备考题库及答案解析
评论
0/150
提交评论