在C++中,重载(Overloading)和重写(Overriding)是两个不同的概念,它们适用于不同的上下文和目的。下面是对这两个概念的详细解释及其区别:
1. 重载(Overloading)
重载是指在同一个作用域中定义多个同名的函数,但这些函数具有不同的参数列表(参数的类型、数量或顺序不同)。重载可以应用于普通函数和运算符。
1.1 函数重载
#include <iostream>
class Example {
public:
void print(int i) {
std::cout << "Integer: " << i << std::endl;
}
void print(double d) {
std::cout << "Double: " << d << std::endl;
}
void print(const std::string& s) {
std::cout << "String: " << s << std::endl;
}
};
int main() {
Example ex;
ex.print(42); // 调用 void print(int i)
ex.print(3.14); // 调用 void print(double d)
ex.print("Hello"); // 调用 void print(const std::string& s)
return 0;
}
1.2 运算符重载
#include <iostream>
class Complex {
public:
double real, imag;
Complex(double r, double i) : real(r), imag(i) {}
Complex operator+(const Complex& other) {
return Complex(real + other.real, imag + other.imag);
}
void print() {
std::cout << real << " + " << imag << "i" << std::endl;
}
};
int main() {
Complex c1(1.0, 2.0);
Complex c2(3.0, 4.0);
Complex c3 = c1 + c2;
c3.print(); // 输出:4 + 6i
return 0;
}
2. 重写(Overriding)
重写是指在派生类中重新定义基类中已存在的虚函数(virtual function)。重写必须与基类的虚函数具有相同的函数签名(参数类型、数量和返回类型都相同)。重写主要用于实现多态性(polymorphism),即通过基类指针或引用调用派生类的函数。
2.1虚函数重写
#include <iostream>
class Base {
public:
virtual void show() const {
std::cout << "Base show()" << std::endl;
}
virtual ~Base() = default; // 虚析构函数
};
class Derived : public Base {
public:
void show() const override {
std::cout << "Derived show()" << std::endl;
}
};
int main() {
Base* b = new Derived();
b->show(); // 调用 Derived::show()
delete b;
return 0;
}
3. 总结
- 重载与重写的区别
特性 | 重载(Overloading) | 重写(Overriding) |
---|---|---|
适用范围 | 同一作用域 | 基类和派生类 |
参数列表 | 必须不同(参数类型、数量或顺序至少有一个不同) | 必须相同(参数类型、数量和顺序完全相同) |
返回类型 | 可以不同 | 必须相同 |
虚函数 | 不要求 | 基类函数必须是虚函数 |
使用场景 | 实现同名函数的不同功能 | 实现多态性,基类指针或引用调用派生类函数 |
- 重载:在同一个作用域内允许存在多个同名函数,通过不同的参数列表区分这些函数。重载通常用于提供函数的多种版本,以便在不同情况下使用。
- 重写:在派生类中重新定义基类中的虚函数,使得通过基类指针或引用可以调用派生类中的实现。重写用于实现多态性。