1 / 43

12 多載函數

12.1 多載概論 12-2 12.1.1 多載一般函數 12-2 12.1.2 多載成員函數 12-3 12.1.3 多載建立者函數 12-5 12.2 多載運算符號 12-8 12.2.1 多載運算符號限制 12-9 12.2.2 運算符號函數 12-12 12.2.3 多載 >> 運算符號 12-12 12.2.4 多載 << 運算符號 12-13 12.2.5 多載雙運算元符號 12-16 12.2.6 多載單運算元符號 12-20.

judson
Download Presentation

12 多載函數

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 12.1多載概論 12-2 12.1.1 多載一般函數 12-2 12.1.2 多載成員函數 12-3 12.1.3 多載建立者函數 12-5 12.2多載運算符號 12-8 12.2.1 多載運算符號限制 12-9 12.2.2 運算符號函數 12-12 12.2.3 多載 >> 運算符號 12-12 12.2.4 多載 << 運算符號 12-13 12.2.5 多載雙運算元符號 12-16 12.2.6 多載單運算元符號 12-20 12.2.7 多載前置運算符號 12-23 12.2.8 多載後置運算符號 12-23 12.3轉換型態 12-26 12.3.1 基本型態轉基本型態 12-26 12.3.2 基本型態轉類別型態 12-27 12.3.3 類別型態轉基本型態 12-29 12.3.4 類別型態轉類別型態 12-31 12 多載函數

  2. 12.1 多載概論 • 多載(overloading)就是重複定義多個相同名稱的函數,但這些函數的功能不完全相同。所以多載函數的情況包括:(1)接收不同數量的參數,(2)傳遞不同型態的參數,(3)傳回不同型態的參數。

  3. 12.1.1 多載一般函數 • 範例 int area(int length, int width); //第一個area { return length * width; } double area(int radius) //第二個area函數 { return 3.1415926 * pow(radius, 2); } int main() { int rectangleArea = area(3, 5); //呼叫第一個area函數 double circleArea = area(5); //呼叫第二個area函數 return 0; //正常結束程式 }

  4. 12.1.2 多載成員函數 • 多載函數的情況包括:(1)接收不同數量的參數,(2)傳遞不同型態的參數,(3)傳回不同型態的參數。 • 範例一 class Cuboid //宣告長方體類別 { private: int length; //Cuboid的資料成員1 int width; //Cuboid的資料成員2 int height; //Cuboid的資料成員3

  5. 12.1.2 多載成員函數 (續) • 範例續 public: int area() { //錯誤,Multiple declaration return length * width; } int area() { //錯誤,Multiple declaration return 2 * (length * width + width * height + height * length); } };

  6. 12.1.2 多載成員函數 (續) • 範例二 class Cuboid //宣告長方體類別 { int length; //Cuboid的資料成員1 int width; //Cuboid的資料成員2 int height; //Cuboid的資料成員3 public: void setSide(int l, int w) //設定長方形邊長 { length = l; width = w; height = 0; }

  7. 12.1.2 多載成員函數 (續) • 範例續 void setSide(int l, int w, int h) //設定長方體邊長 { length = l; width = w; height = h; } int area() //計算長方體表面積函數 { return 2 * (length * width + width * height + height * length); } };

  8. 12.1.3 多載建立者函數 • 在類別中可以多載(overload)建立者函數,也就是定義多個建立者函數,每個建立者函數可含有不同個數的參數。 • 範例 class Timer { int seconds; public: Timer() { //定義無參數建立者 seconds = 0;} Timer(int s) { //定義整數參數建立者 seconds = s;}

  9. 12.1.3 多載建立者函數 (續) • 範例續 Timer(char *t) { //定義指標參數建立者 seconds = atoi(t);} }; int main() { char str[20] = "250"; Timer t1; //t1.seconds = 0 Timer t2(10); //t2.seconds = 10 Timer t3(str); //t3.seconds = 250 return 0; //正常結束程式 }

  10. Exercise • 建立一個Circle類別 • 定義private資料成員radius • 定義無參數建立者函數,設定radius=1 • 定義一個參數建立者函數,設定radius=參數 • 定義public成員函數area,計算圓面積 • 撰寫main()函數,宣告兩個Circle的物件變數,一個有參數,另一無參數,分別呼叫area函數後印出各自的圓面積

  11. 12.2 多載運算符號 • 在C++ 語言中,<< 運算符號可以配合cout敘述作為字串輸出運算符號,也可以作為左移位元運算符號;同理,>> 運算符號可以配合cin敘述作為字串輸入運算符號,也可以作為右移位元運算符號。這就是運算符號多載(operator overloading)。 • 運算符號多載(operator overloading),就是要再定義這些運算符號,使它們也能接受使用者自定的資料型態與物件。

  12. 12.2.1 多載運算符號限制 • 可以被多載的運算符號包括表12.1算術運算符號、表12.2關係與邏輯運算符號、表12.3位元運算符號、表12.4指定運算符號、表12.5特殊運算符號。 • 表中同時提供這些運算符號在C++ 的內建功能、範例與說明,設計師為自定資料型態多載這些符號時,必須保持它們原來的功能,否則將會造成語法錯誤訊息。 • 例如,將 + 多載為減法運算符號,編譯時會出現語法錯誤訊息。

  13. 12.2.2 運算符號函數 • 運算符號函數可以是類別成員函數或非類別成員函數。當非成員函數或非friend函數要存取私用區(private)或保護區(protected)的資料時,必須先呼叫公用區(public)的set或get成員函數,如此將會降低程式的性能。 • 所以為了得到更好的性能,可使用friend函數,friend雖然不是類別成員函數但仍可直接存取私用區(private)或保護區(protected)的資料。

  14. 12.2.3 多載 >> 運算符號 • friend istream &operator>>(istream&傳回參數, 類別名稱 物件參數) • 範例 class Test { private: int a, b; //定義private變數 public: Test() { a = b = 0; }

  15. 12.2.3 多載 >> 運算符號 (續) • 範例續 Test(int n, int m) { a = n; b = m; } }; int main() { Test s1; cin >> s1; //錯誤不能輸入Test型態資料 cout << s1; //錯誤不能輸出Test型態資料 return 0; //正常結束程式 }

  16. 12.2.4 多載 << 運算符號 • friend ostream &operator<<(ostream&傳回參數, 類別名稱 物件參數) • 範例 class Test { private: int a, b; //定義private變數 public: Test() { a = b = 0; }

  17. 12.2.4 多載 << 運算符號 (續) • 範例續 Test(int n, int m) { a = n; b = m; } friend istream& operator>>(istream& in, Test& obj); friend ostream& operator<<(ostream& out, Test& obj); }; istream& operator>>(istream& in, Test& obj) { cout << "請輸入a與b之值:"; in >> obj.a >> obj.b; return in; }

  18. 12.2.4 多載 << 運算符號 (續) • 範例續 ostream& operator<<(ostream& out, Test& obj) { out << "a 與 b 的值:" << endl; out << obj.a << " " << obj.b << endl; return out; } int main() { Test s1; cin >> s1; //若輸入2 3 cout << s1; //則輸出2 3 return 0; //正常結束程式 }

  19. 12.2.5 多載雙運算元符號 • 傳回型態 operator運算符號(類別型態 物件參數) • 傳回型態 operator運算符號(類別1 物件1, 類別2 物件2) • 範例 class Test { int a, b; //定義private變數 public: Test() { a = b = 0; } Test(int n, int m) { a = n; b = m; } Test operator+(Test); //宣告多載 + 號 };

  20. 12.2.5 多載雙運算元符號 (續) • 範例一續 Test Test::operator+(Test obj) { //定義多載 + 號 Test temp; temp.a = a + obj.a; //a=s1.a, obj.a=s2.a temp.b = b + obj.b; //b=s1.b, obj.b=s2.b return temp; } int main() { Test s1(2, 3), s2(4, 5), s3; s3 = s1 + s2; //s1.operator+(s2) return 0; //正常結束程式 }

  21. 12.2.5 多載雙運算元符號 (續) • 範例二 class Test { int a; //定義private變數 public: Test() { a = 0; } Test(int n) { a = n; } bool operator>(Test); //宣告多載 > 號 }; bool Test::operator>(Test obj) { //定義多載 > 號 if (a > obj.a) return true; else return false; }

  22. 12.2.5 多載雙運算元符號 (續) • 範例二續 int main() { Test s1(2), s2(5); if (s1 > s2) //呼叫多載 > 函數 cout << "s1 > s2"; else cout << "s1 < s2"; return 0; //成功結束程式 }

  23. 12.2.6 多載單運算元符號 • 傳回型態 operator運算符號() • 傳回型態 operator運算符號(類別型態 物件參數) • 範例 class Test { int a; //定義private變數 public: Test(int n) { a = n; } bool operator !(); //宣告多載 ! 號 };

  24. 12.2.6 多載單運算元符號 (續) • 範例續 bool Test::operator!() { //定義多載 ! 號 if (a != 0) {return true;} else {return false;} } int main() { Test s1(5); if (!s1) {cout << "s1 != 0"; } //呼叫多載 ! 符號函數 else {cout << "s1 == 0";} return 0; //正常結束程式 }

  25. 12.2.7 多載前置運算符號 • 傳回型態 operator運算符號() • 範例 class Test { int a, b; //定義private變數 public: Test() { a = b = 0; } Test(int n, int m) { a = n; b = m; } Test operator++(); //宣告前置 ++x 號 };

  26. 12.2.7 多載前置運算符號 (續) • 範例續 Test Test::operator++() //定義前置 ++x 號 { return Test(++a, ++b); } int main() { Test s1(2, 3), s2; s2 = ++s1; //等於s1.operator++() return 0; //正常結束程式 }

  27. 12.2.8 多載後置運算符號 • 傳回型態 operator運算符號(int) • 範例 class Test { int a, b; //定義private變數 public: Test() { a = b = 0; } Test(int n, int m) { a = n; b = m; } Test operator++(int); //宣告後置 x++ 號 };

  28. 12.2.8 多載後置運算符號 (續) • 範例續 Test Test::operator++(int) //定義後置 x++ 號 { return Test(a++, b++); } int main() { Test s1(2, 3), s2; s2 = s1++; //s2.a=s1.a=2, s2.b=s1.b=3 //s1.a=++s1.a=3, s1.b=++s1.b=4 return 0; //正常結束程式 }

  29. Exercise • 建立一個Counter類別 • 定義private資料成員count • 定義建立者函數並設定count=0 • 定義成員函數getcount() • 重載++ • 撰寫main()函數,宣告一個Counter的物件變數,呼叫兩次++後,印出count值

  30. 12.3 轉換型態

  31. 12.3.1 基本型態轉基本型態 • float型態的fracfeet轉成int型態的feet int feet; float fracfeet = 3.280833 * 3.5; feet = int(fracfeet); //float轉成int • int型態的fracfeet轉成float型態的fracfeet int feet; float fracfeet = inch / 12; fracfeet = float(feet); //feet從int轉為float

  32. 12.3.2 基本型態轉類別型態 • float型態的資料轉成Distance型態 const float MTF = 3.280833f; class Distance //宣告Distance類別 { int feet; float inch; public: Distance (int f, float in) //宣告一參數建立者 { feet = f; inch = in; }

  33. 12.3.2 基本型態轉類別型態 (續) • 範例續 Distance (float meter) { //宣告二參數建立者 float fracfeet = MTF * meter; feet = (int)fracfeet; inch = 12 * (fracfeet - feet); } }; int main() { Distance d(0, 0); //呼叫二個參數的建立者 float m = 3.5; //m = 3.5 m d = m; //呼叫一個參數的建立者 return 0; //正常結束程式 }

  34. 12.3.3 類別型態轉基本型態 • Distance型態的資料轉成float型態 • 範例 const float MTF = 3.280833; class Distance //宣告Distance類別 { int feet; float inch; public: Distance (int f, float in) //Distance類別建立者 { feet = f; inch = in; }

  35. 12.3.3 類別型態轉基本型態 (續) • 範例續 operator float() { //多載float型態函數 float fracfeet = inch / 12; fracfeet = float(feet); return fracfeet / MTF; } }; int main() { Distance d(2, 3); //呼叫Distance建立者 float m; //宣告浮點數變數m m = d; //呼叫operator float函數 return 0; //正常結束程式 }

  36. 12.3.4 類別型態轉類別型態 • Polar型態的資料轉成Cartesian型態 class Cartesian { //宣告 Cartesian 類別 double x; double y; public: Cartesian () {x = y = 0.0;} }; class Polar { //宣告Polar類別 double radius; double angle; public: Polar(double r, double a) { radius = r; angle = a; }

  37. 12.3.4 類別型態轉類別型態 (續) • 範例續 operator Cartesian() { //多載Cartesian函數 double xx, yy; xx = radius * cos(angle); yy = radius * sin(angle); return Cartesian(xx, yy); } }; int main() { Polar p(2.0, 35.0); //建立極座標p點位置 Cartesian c; //建立平面座標c c = p; //呼叫Cartesian函數 return 0; //正常結束程式 }

  38. 12.3.4 類別型態轉類別型態 (續) • Polar型態的資料轉成Cartesian型態 • 範例 class Polar //宣告Polar類別 { double radius; double angle; public: Polar(double r, double a) { radius = r; angle = a; } double getr() {return radius;} double geta() {return angle;} };

  39. 12.3.4 類別型態轉類別型態 (續) class Cartesian { //宣告Cartesian類別 double x; double y; public: Cartesian() {x = y = 0.0;} Cartesian(double a, double b) {x = a; y = b;} Cartesian operator = (Polar p) { //定義多載 = 號函數 double r = p.getr(); double a = p.geta(); x = r * cos(a); y = r * sin(a); return Cartesian(x, y); } };

  40. 12.3.4 類別型態轉類別型態 (續) • 範例 int main() { Polar p(2.0, 35.0); //建立極座標p點位置 Cartesian c; //建立平面座標c c = p; //呼叫多載 = 號函數 return 0; //正常結束程式 }

  41. Exercise • 類別Polar3D • 定義私有資料成員:range, azimuth, elevation • 定義公有成員函數: • 三參數的建構子:設定資料成員初值 • 3個get函數 • 類別Cartesian3D • 定義私有資料成員:x, y, z • 定義公有成員函數: • 無參數建構子:設定資料成員初值 • operator= :將極座標轉換為笛卡兒 座標 • show:印出x, y, z座標值 • 撰寫main函數 • 宣告Polar3D及Cartesian3D的物件變數 • 將Polar3D物件轉換型態為Cartesian3D物件 • 呼叫show函數印出其值

More Related