過載(Overloading)
1. 過載(Function Overloading)
- 概念:函式過載是指在相同的作用域記憶體在多個具有相同名稱但引數列表不同的函式。
- 語法:函式名相同,但引數的型別、數量或順序不同。
- 特點:編譯器透過引數列表來區分不同的函式。
示例程式碼:
void print(int i) {
std::cout << "Integer: " << i << std::endl;
}
void print(double f) {
std::cout << "Double: " << f << std::endl;
}
void print(const std::string& s) {
std::cout << "String: " << s << std::endl;
}
int main() {
print(10); // 呼叫 int 版本的 print
print(20.5); // 呼叫 double 版本的 print
print("Kimi"); // 呼叫 string 版本的 print
return 0;
}
2. 重寫(Overriding)
- 概念:函式重寫是指在派生類中重新定義基類中的虛擬函式。
- 語法:派生類的函式與基類中的虛擬函式具有相同的名稱和引數列表。
- 特點:當透過基類指標或引用呼叫該函式時,會根據物件的實際型別呼叫相應的函式。
示例程式碼:
class Base {
public:
virtual void show() const {
std::cout << "Base class show()" << std::endl;
}
};
class Derived : public Base {
public:
void show() const override { // 重寫基類的show()
std::cout << "Derived class show()" << std::endl;
}
};
int main() {
Base* b = new Derived();
b->show(); // 呼叫 Derived 的 show()
delete b;
return 0;
}
3. 友元(Friend)
- 概念:友元是指可以訪問類的私有和保護成員的非成員函式或另一個類的成員函式。
- 語法:在類定義中使用
friend
關鍵字宣告友元函式或友元類。 - 特點:友元關係不是繼承的,且友元函式不屬於任何類。
示例程式碼:
class MyClass {
private:
int value;
public:
MyClass(int val) : value(val) {}
friend void printValue(const MyClass& obj);
};
void printValue(const MyClass& obj) {
std::cout << "Value: " << obj.value << std::endl;
}
int main() {
MyClass obj(10);
printValue(obj); // 訪問私有成員
return 0;
}
4. 二義性問題(Ambiguity)
- 概念:當一個函式呼叫可以匹配多個過載版本時,會產生二義性問題。
- 特點:編譯器無法確定呼叫哪個函式,導致編譯錯誤。
示例程式碼:
void func(int);
void func(int, double);
int main() {
func(1); // 二義性:匹配了 func(int),但 func(int, double) 也可以透過預設引數匹配
return 0;
}
5. 運算子過載(Operator Overloading)
- 概念:運算子過載是指為已有的運算子賦予新的功能,以用於使用者定義的型別。
- 語法:透過過載運算子作為類的成員函式或友元函式。
- 特點:大多數運算子都可以過載,除了
.
、::
、.*
和?:
等。
示例程式碼:
class Complex {
public:
double real;
double imag;
Complex(double r, double i) : real(r), imag(i) {}
// 成員函式運算子過載
Complex operator+(const Complex& other) const {
return Complex(real + other.real, imag + other.imag);
}
// 友元運算子過載
friend std::ostream& operator<<(std::ostream& os, const Complex& c);
};
std::ostream& operator<<(std::ostream& os, const Complex& c) {
os << c.real << "+" << c.imag << "i";
return os;
}
int main() {
Complex c1(2, 3), c2(4, 5);
Complex c3 = c1 + c2;
std::cout << c3; // 使用過載的<<運算子
return 0;
}
6. 不可過載的運算子
- 概念:一些運算子不能被過載。
- 特點:這些運算子包括
.
、::
、.*
、?:
等。
示例程式碼:
// 以下嘗試會導致編譯錯誤
class MyClass {
public:
int data;
// 錯誤:嘗試過載成員訪問運算子
MyClass operator.(int index) {
return data;
}
};
運算子過載提供了一種方便的方式來定義自定義型別的操作,但需要謹慎使用,以避免混淆或誤用。