多态 (Polymorphism) 是面向对象编程中的一个重要特性,它允许同一个操作或函数在不同的情况下有不同的表现方式。C++中的多态分为静态多态动态多态

静态多态

静态多态是在编译时决定调用哪个函数或操作,它主要通过函数重载和运算符重载实现。

函数重载

函数重载是指在同一作用域内,可以定义多个同名函数,但它们的参数列表(参数类型、参数个数、参数顺序)必须不同。编译器在编译时根据函数调用时的参数列表来确定调用哪个函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
using namespace std;

class Math {
public:
int add(int a, int b) {
return a + b;
}
double add(double a, double b) {
return a + b;
}
};

int main() {
Math math;
cout << math.add(1, 2) << endl; // 调用int add(int, int)
cout << math.add(1.5, 2.5) << endl; // 调用double add(double, double)
return 0;
}

运算符重载

C++可以重定义或重载大部分 C++ 内置的运算符。这样,就能使用自定义类型的运算符。
重载的运算符是带有特殊名称的函数,函数名是由关键字 operator 和其后要重载的运算符符号构成的。与其他函数一样,重载运算符有一个返回类型和一个参数列表。
可重载的运算符列表:

名称 表示
双目算术运算符 + (加),-(减),*(乘),/(除),% (取模)
关系运算符 ==(等于),!= (不等于),< (小于),> (大于),<=(小于等于),>=(大于等于)
逻辑运算符 ||(逻辑或),&&(逻辑与),!(逻辑非)
单目运算符 + (正),-(负),*(指针),&(取地址)
自增自减运算符 ++(自增),—(自减)
位运算符 |(按位或),& (按位与),~(按位取反),^(按位异或),,<< (左移),>>(右移)
赋值运算符 =, +=, -=, *=, /= , % = , &=, =, ^=, <<=, >>=
空间申请与释放 new, delete, new[ ] , delete[]
其他运算符 ()(函数调用),->(成员访问),,(逗号),

不可重载的运算符列表:

.成员访问运算符
.*,->*成员指针访问运算符
::域运算符
sizeof长度运算符
? :条件运算符
#预处理符号

运算符重载是通过在类中定义一个与运算符相对应的成员函数或友元函数实现的。
成员函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
using namespace std;

class Complex {
public:
double real, imag;

Complex(double r, double i) : real(r), imag(i) {}

// 重载加法运算符
Complex operator+(const Complex& c) const {
return Complex(real + c.real, imag + c.imag);
}

void display() const {
cout << real << " + " << imag << "i" << endl;
}
};

int main() {
Complex c1(1.2, 3.4), c2(5.6, 7.8);
Complex c3 = c1 + c2; // 使用重载的加法运算符
c3.display(); // 输出 6.8 + 11.2i
return 0;
}

友元函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>
using namespace std;

class Complex {
private:
double real, imag;

public:
Complex(double r, double i) : real(r), imag(i) {}

// 声明友元函数
friend Complex operator+(const Complex& c1, const Complex& c2);

void display() const {
cout << real << " + " << imag << "i" << endl;
}
};

// 友元函数实现运算符重载
Complex operator+(const Complex& c1, const Complex& c2) {
return Complex(c1.real + c2.real, c1.imag + c2.imag);
}

int main() {
Complex c1(1.2, 3.4), c2(5.6, 7.8);
Complex c3 = c1 + c2; // 调用友元函数 operator+
c3.display(); // 输出 6.8 + 11.2i
return 0;
}

函数模板

模板允许定义通用的函数或类,编译器在编译时会根据实际传递的类型生成对应的函数或类实例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
using namespace std;

// 函数模板
template <typename T>
T add(T a, T b) {
return a + b;
}

int main() {
cout << add(10, 20) << endl; // 调用 int 类型的 add
cout << add(1.5, 2.5) << endl; // 调用 double 类型的 add
return 0;
}

动态多态

动态多态 (Dynamic Polymorphism) 是面向对象编程中的一种重要特性,它允许程序在运行时根据对象的实际类型调用相应的函数版本,而不是在编译时确定。这种行为通过虚函数 (virtual function) 和继承 (inheritance) 机制实现。
动态多态的核心

  • 继承 (Inheritance):基类和派生类之间的关系是实现多态的基础。
  • 虚函数 (Virtual Function):在基类中声明为virtual的成员函数允许派生类重写,并在运行时动态绑定到对象的实际类型。
  • 基类指针或引用:通过基类的指针或引用调用虚函数,动态决定调用基类或派生类的实现。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <iostream>
using namespace std;

class Base {
public:
virtual void show() { // 虚函数
cout << "Base class show() called" << endl;
}

virtual ~Base() { // 虚析构函数
cout << "Base class destructor called" << endl;
}
};

class Derived : public Base {
public:
void show() override { // 使用 override 标明重写
cout << "Derived class show() called" << endl;
}

~Derived() {
cout << "Derived class destructor called" << endl;
}
};

int main() {
Base* ptr = new Derived(); // 基类指针指向派生类对象
ptr->show(); // 动态绑定,调用 Derived::show()

delete ptr; // 动态绑定,调用 Derived 和 Base 的析构函数
return 0;
}

/*输出
Derived class show() called
Derived class destructor called
Base class destructor called
*/

如果基类中的虚函数没有具体实现,可以将其声明为纯虚函数,派生类必须重写该函数。