360 likes | 508 Vues
運算子多載. 鄭士康 國立台灣大學 電機工程學系 / 電信工程研究所 / 資訊網路與多媒體研究所. 運算子多載. 可以多載 一元 : + 、 - 、 ! 、 ~ 、 ++ 、 -- 、 true 、 false 二元: + 、 - 、 * 、 / 、 % 、 & 、 | 、 ^ 、 << 、 >> 、 == 、 != 、 > 、 < 、 >= 、 <= 不可多載
E N D
運算子多載 鄭士康 國立台灣大學 電機工程學系/電信工程研究所/ 資訊網路與多媒體研究所
運算子多載 • 可以多載 • 一元:+、-、!、~、++、--、true、false • 二元:+、-、*、/、%、&、|、^、<<、>>、==、!=、>、<、>=、<= • 不可多載 • =、.、&&、||、?:、[] 、() 、->、new、is、sizeof、typeof、+=、-=、*=、/=、%=、&=、|=、^=、<<=、>>= • 轉換運算子 • explicit 關鍵字 • Implicit 關鍵字
UsingOperOverload.Program(1/2) using System; namespace UsingOperOverload { /* 示範一元運算子多載 * 4/9/2007 */ class Program { static void Main(string[] args) { Rectangle rec = new Rectangle(100, 50); Console.WriteLine("長方形rec的面積: " + rec.Area());
UsingOperOverload.Program(2/2) rec++; Console.WriteLine("長方形rec++後的面積: " + rec.Area()); // 應為 5151 ++rec; Console.WriteLine("長方形++rec後的面積: " + rec.Area()); // 應為 5304 Console.ReadLine(); } } }
UsingOperOverload.Rectangle(1/2) using System; namespace UsingOperOverload { public class Rectangle { private int width; private int length; private int area; public Rectangle(int width, int length) { this.width = width; this.length = length; area = width * length; }
UsingOperOverload.Rectangle(2/2) public int Area() { return area; } public static Rectangle operator ++(Rectangle op) { Rectangle result = new Rectangle(op.width+1, op.length+1); return result; } } }
UsingOperOverload2.Program(1/2) using System; namespace UsingOperOverload2 { /* * 示範二元運算子多載的應用 * 4/9/2007 */ class Program { static void Main(string[] args) { Rectangle rec1 = new Rectangle(100, 50); Rectangle rec2 = new Rectangle(90, 25); Rectangle recSum = rec1 + rec2; Rectangle recDif = rec1 - rec2;
UsingOperOverload2.Program(2/2) // recSum.Area() 應為14250 Console.WriteLine("rec1 + rec2 的面積: " + recSum.Area()); // recDif.Area() 應為250 Console.WriteLine("rec1 - rec2 的面積: " + recDif.Area()); Console.ReadLine(); } } }
練習 • 撰寫測試主程式及類別Rational(有理數),其中須測試及定義有理數+、-、*、/、++運算子。可不必考慮約分。
UsingOperOverload3.Program(1/2) using System; namespace UsingOperOverload3 { /* * 示範不同型別運算元之二元運算子多載 * 4/9/2007 */ class Program { static void Main(string[] args) { StudentClass cls = new StudentClass(20); StudentClass clsAfterAdd = cls + 10; StudentClass clsAfterSub = cls - 3; Console.WriteLine("加選後班級人數: " + clsAfterAdd.accessNStudents);
UsingOperOverload3.Program(2/2) Console.WriteLine("退選後班級人數: " + clsAfterSub.accessNStudents); Console.ReadLine(); } } }
UsingOperOverload3.StudentClass(1/3) using System; namespace UsingOperOverload3 { public class StudentClass { private int nStudents; public StudentClass(int nStudents) { if (nStudents < 0) { this.nStudents = 0; } else { this.nStudents = nStudents; } }
UsingOperOverload3.StudentClass(2/3) public int accessNStudents { get { return nStudents; } } public static StudentClass operator +(StudentClass op1, int op2) { StudentClass result = new StudentClass(op1.nStudents + op2); return result; }
UsingOperOverload3.StudentClass(3/3) public static StudentClass operator – (StudentClass op1, int op2) { StudentClass result = new StudentClass(op1.nStudents - op2); return result; } } }
LogOperOverload.Program(1/2) using System; namespace LogOperOverload { /* * 示範邏輯運算子之多載 * 4/10/2007 */ class Program { static void Main(string[] args) { StudentClass clsA = new StudentClass(30); StudentClass clsB = new StudentClass(40); StudentClass clsC = new StudentClass(0); bool canMerge = clsA & clsB;
LogOperOverload.Program(2/2) string message = canMerge ? "A班與B班可合併" : "A班與B班不可合併"; Console.WriteLine(message); bool canNotCancel = !clsC; message = canNotCancel ? "C班不可裁撤" : "C班可裁撤"; Console.WriteLine(message); Console.ReadLine(); } } }
LogOperOverload.StudentClass(1/3) using System; namespace LogOperOverload { public class StudentClass { private int nStudents; public StudentClass(int nStudents) { if (nStudents < 0) { this.nStudents = 0; } else { this.nStudents = nStudents; } }
LogOperOverload.StudentClass(2/3) public int accessNStudents { get { return nStudents; } } public static bool operator &(StudentClass op1, StudentClass op2) { bool result = op1.nStudents+op2.nStudents < 50; return result; }
LogOperOverload.StudentClass(3/3) public static bool operator !(StudentClass op) { bool result = op.nStudents > 0; return result; } } }
RelOperOverload.Program(1/2) using System; namespace RelOperOverload { /* * 示範關聯運算子>和<的多載 * 4/11/2007 */ class Program { static void Main(string[] args) { StudentClass clsA = new StudentClass(20); StudentClass clsB = new StudentClass(30); bool clsAIsLarger = clsA > clsB; string message = clsAIsLarger ? "A班人數大於B班" : "A班人數不大於B班";
RelOperOverload.Program(2/2) Console.WriteLine(message); Console.ReadLine(); } } }
RelOperOverload.StudentClass(1/3) using System; namespace RelOperOverload { public class StudentClass { private int nStudents; public StudentClass(int nStudents) { if (nStudents < 0) { this.nStudents = 0; } else { this.nStudents = nStudents; } }
RelOperOverload.StudentClass(2/3) public int accessNStudents { get { return nStudents; } } public static bool operator >(StudentClass op1, StudentClass op2) { bool result = (op1.nStudents > op2.nStudents); return result; }
RelOperOverload.StudentClass(3/3) public static bool operator <(StudentClass op1, StudentClass op2) { bool result = (op1.nStudents < op2.nStudents); return result; } } }
練習 • 在類別Rational(有理數)中添加有理數>、<、!(檢驗是否為0)運算子,並予測試。 • 處理Rational(有理數)類別與整數進行+、-、*、/的情形
RelOperOverload.Program(1/2) using System; namespace RelOperOverload2 { /* * 示範關聯運算子==,!=,Equals,GetHashCode等的多載 * 4/11/2007 */ class Program { static void Main(string[] args) { StudentClass clsA = new StudentClass("A", 20); StudentClass clsB = new StudentClass("B", 20); bool clsAEqualsclsB = clsA == clsB; string message = clsAEqualsclsB ? “clsA與clsB相等”: “clsA與clsB不等";
RelOperOverload.Program(2/2) Console.WriteLine(message); clsAEqualsclsB = clsA.Equals(clsB); message = clsAEqualsclsB ? “clsA與clsB相等": “clsA與clsB不等"; Console.WriteLine(message); Console.ReadLine(); } } }
RelOperOverload2.StudentClass(1/3) using System; namespace RelOperOverload2 { public class StudentClass { private int nStudents; private string name; public StudentClass(string name, int nStudents) { this.name = name; if (nStudents < 0) { this.nStudents = 0; }
RelOperOverload2.StudentClass(2/3) else { this.nStudents = nStudents; } } public static bool operator ==(StudentClass op1, StudentClass op2) { bool result = ( op1.name.Equals(op2.name) ) && (op1.nStudents == op2.nStudents); return result; } public static bool operator !=(StudentClass op1, StudentClass op2) { return !(op1 == op2); }
RelOperOverload2.StudentClass(3/3) public override bool Equals(object obj) { bool result = false; if (obj is StudentClass){ StudentClass op = (StudentClass) obj; result = name.Equals(op.name) && (nStudents == op.nStudents); } return result; } public override int GetHashCode(){ return nStudents.GetHashCode() + name.GetHashCode(); } } }
ConverOper.Program (1/2) using System; namespace ConverOper { /* * 示範explicit與implicit的轉換 * 4/11/2007 */ class Program { static void Main(string[] args) { Rectangle rec = new Rectangle(15, 10); int area = (int) rec; Console.WriteLine("rec面積為" + area); Square sq = new Square(20);
ConverOper.Program (2/2) rec = sq; area = (int)rec; Console.WriteLine("sq面積為" + area); Console.ReadLine(); } } }
ConverOper.Rectangle (1/2) using System; namespace ConverOper { public class Rectangle { int width; int length; int area; public Rectangle(int width, int length) { this.width = width; this.length = length; area = length * width; }
ConverOper.Rectangle (2/2) public static explicit operator int(Rectangle op) { return op.area; } } }
ConverOper.Square using System; namespace ConverOper { public class Square{ private int width; public Square(int width){ this.width = width; } public static implicit operator Rectangle( Square op ) { Rectangle rec = new Rectangle( op.width, op.width ); return rec; } } }
練習 • 在類別Rational(有理數)中添加有理數==、!=運算子及Equals、GetHashCode方法,並予測試。 • 在類別Rational(有理數)中添加轉為double的explicit運算子,及int轉為Rational的implicit運算子