重载(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;
}
};
运算符重载提供了一种方便的方式来定义自定义类型的操作,但需要谨慎使用,以避免混淆或误用。
作者:
hwaityd
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文连接,否则保留追究法律责任的权利。