## 🔄 第五週:運算子多載(Operator Overloading) --- - **學習目標:** - 認識運算子多載的用途 - 學會實作常見運算子的多載 - 提升物件的使用直覺性與便利性 --- ## 🔖 什麼是運算子多載? - **Operator Overloading** 定義類別運算子的行為,使物件能直接使用各種運算子(如 `+`, `-`, `<<` 等)。 - 提升程式碼可讀性,讓物件用起來像內建型別一樣自然。 ---- ```cpp Complex a(1,2), b(3,4); Complex c = a + b; // 運算子多載後即可直接使用+ ``` --- ## 📌 運算子多載的語法規則 ```cpp return_type operator symbol(parameters){ // ... } ``` - 可以用 `成員函式` 或 `非成員函式` 實作。 Note: - 非成員函式 - 非成員函式是獨立於任何類別的函式,它不屬於任何物件(object),通常是定義在類別外的函式。 ```cpp #include <iostream> #include <cmath> using namespace std; class Point { public: int x, y; Point(int x, int y) : x(x), y(y) {} }; // 非成員函式 double distance(const Point& a, const Point& b) { int dx = a.x - b.x; int dy = a.y - b.y; return sqrt(dx * dx + dy * dy); } int main() { Point p1(1, 2), p2(4, 6); cout << distance(p1, p2) << endl; return 0; } ``` ---- ## 🚩 範例:複數 ```cpp class Complex { private: int real, imag; public: Complex(int r, int i) : real(r), imag(i) {} // 使用成員函式多載 + Complex operator+(const Complex &c) { return Complex(real + c.real, imag + c.imag); } void show() { cout << real << "+" << imag << "i" << endl; } }; ``` ---- ### 使用方式: ```cpp Complex c1(1,2), c2(3,4); Complex c3 = c1 + c2; // 使用 + 運算子 c3.show(); // 4+6i ``` --- ### 📗 非成員函式實作多載 - 運算子多載也可使用非成員函式(常與 `friend` 一起使用) ```cpp class Complex { private: int real, imag; public: Complex(int r, int i) : real(r), imag(i) {} void show() const { cout << real << "+" << imag << "i" << endl; } // friend 函式:Complex + Complex friend Complex operator+(const Complex &a, const Complex &b); // friend 函式:Complex + int friend Complex operator+(const Complex &a, int b); // friend 函式:int + Complex friend Complex operator+(int a, const Complex &b); }; // Complex + Complex Complex operator+(const Complex &a, const Complex &b) { return Complex(a.real + b.real, a.imag + b.imag); } // Complex + int Complex operator+(const Complex &a, int b) { return Complex(a.real + b, a.imag); } // int + Complex Complex operator+(int a, const Complex &b) { return Complex(a + b.real, b.imag); } ``` ---- ### 使用 ```cpp #include <iostream> using namespace std; int main() { Complex c1(3, 4), c2(1, 2); Complex result1 = c1 + c2; // Complex + Complex Complex result2 = c1 + 5; // Complex + int Complex result3 = 5 + c1; // int + Complex result1.show(); // 4+6i result2.show(); // 8+4i result3.show(); // 8+4i return 0; } ``` ---- ## 非成員式多載 使用時機 - [為什麼在 C++ 中使用 Non-member Function(非成員函式)](/meu_hsEFQFKPRTkrz4zZ-g) --- ## 🚩 多載輸出運算子 << - 常用來輸出物件內容 ```cpp #include <iostream> using namespace std; class Point { public: int x, y; Point(int x, int y) : x(x), y(y) {} friend ostream& operator<<(ostream &out, const Point &p); }; ostream& operator<<(ostream &out, const Point &p) { out << "(" << p.x << ", " << p.y << ")"; return out; } ``` ---- ### 使用方式: ```cpp Point p(3, 4); cout << p; // (3, 4) ``` ---- ## 練習 - 把 `Complex` 加入 `<<` 輸出運算子 `friend` Note: ```cpp friend ostream& operator<<(ostream& os, const Complex& c); ostream& operator<<(ostream& os, const Complex& c) { os << c.real << " + " << c.imag << "i"; return os; } cout << "c = " << c << endl; ``` --- ## 📗 多載比較運算子 (==, <, >) ```cpp class Point { public: int x, y; Point(int x, int y) : x(x), y(y) {} bool operator==(const Point &p) { return (x == p.x && y == p.y); } }; ``` ---- ### 使用方式: ```cpp Point p1(3,4), p2(3,4); if(p1 == p2) cout << "相同座標!"; ``` --- ## 📗 運算子多載注意事項 - 不可任意改變運算子原本的意義(如 + 做成減法) - 有些運算子不可多載(如., ::, ?:, .*) - 保持直覺且簡單 --- ## 🚩 常用的多載運算子整理 | 運算子 | 說明 | 常見用途 | | --------- | ---------- | ------------------- | | + - * / | 四則運算 | 向量、矩陣、複數 | | << >> | 輸入輸出 | cout 輸出、cin 輸入 | | << >> | 輸入輸出 | cout 輸出、cin 輸入 | | == != < > | 比較運算子 | 物件間比較 | | [] | 存取元素 | 陣列、字串、容器 | | = | 賦值運算子 | 物件複製與初始化 | --- ## 🛠️ 課堂練習 (Lab) - 練習一: - 設計 Vector3D 類別(向量),並多載 + 、 * 及 << 運算子。 - 練習二: - 建立一個分數類別 Fraction,多載 +, -, 及 == 運算子。 Note: ```cpp #include <iostream> #include <fstream> #include <vector> using namespace std; class Vector3d{ private: int x; int y; int z; public: Vector3d(int x, int y, int z ):x(x),y(y),z(z){} // this + a Vector3d operator+(const Vector3d &a){ return Vector3d(x+a.x , y+a.y , z+a.z); } // vector3d * int // int * vector3d friend Vector3d operator*(const Vector3d&a, int b); friend Vector3d operator*(int a, const Vector3d& b); friend ostream& operator<<(ostream &out, const Vector3d&a); }; Vector3d operator*(const Vector3d&a, int b){ return Vector3d( a.x*b ,a.y*b , a.z*b); } Vector3d operator*(int a, const Vector3d& b){ return Vector3d( a*b.x , a*b.y , a*b.z); } ostream& operator<<(ostream &out, const Vector3d&a){ out << a.x << " "<< a.y << " "<< a.z << endl; return out; } int main() { Vector3d a(1, 2, 3); Vector3d b(4, 5, 6); Vector3d c = 3 * b; // 使用 + 運算子 Vector3d c1 = b * 3; // 使用 + 運算子 ofstream fout("output.txt"); fout << c; return 0; } ``` --- ## 💡 本週作業 - 設計一個 String 類別,支援串接(+)與相等(==)運算子。
{"title":"🔄 運算子多載(Operator Overloading)","description":"學習目標:","contributors":"[{\"id\":\"01487228-6720-47a9-875f-2f01b5d455ad\",\"add\":6594,\"del\":1173,\"latestUpdatedAt\":1753861761013}]"}
    98 views