C++中的多态是面向对象编程的重要特性,允许相同的接口调用不同的实现。多态性可以分为两类:静态多态和动态多态。
1. 静态多态 (编译时多态)
(1)函数重载 (Function Overloading):
函数重载是一种静态多态,允许同一个函数名在同一作用域内具有不同的参数列表。这些不同的版本在编译时根据参数类型和数量区分。
#include<iostream>
using namespace std;
class Print {
public:
void show(int x) {
cout << "Integer: " << x << endl;
}
void show(double x) {
cout << "Double: " << x << endl;
}
void show(string x) {
cout << "String: " << x << endl;
}
};
int main() {
Print print;
print.show(10); // 调用第一个show (int)
print.show(3.14); // 调用第二个show (double)
print.show("Hello"); // 调用第三个show (string)
return 0;
}
(2)模板(Templates):
模板允许编写通用代码,即代码中可以使用不特定数据类型。这种特性也属于静态多态,因为生成具体版本的代码是在编译时进行的。
#include<iostream>
using namespace std;
template <typename T>
class Print {
public:
void show(T x) {
cout << "Value: " << x << endl;
}
};
int main() {
Print<int> printInt;
Print<double> printDouble;
Print<string> printString;
printInt.show(10); // 生成并调用Print<int>::show(int)
printDouble.show(3.14); // 生成并调用Print<double>::show(double)
printString.show("Hello"); // 生成并调用Print<string>::show(string)
return 0;
}
2. 动态多态 (运行时多态)
(1)函数覆盖(Function Overriding):
函数覆盖是指在派生类中重新定义基类中已经存在的虚函数。动态多态是通过虚函数和虚函数表(vtable)机制实现的。
#include<iostream>
using namespace std;
class Base {
public:
virtual void show() {
cout << "Base class" << endl;
}
};
class Derived : public Base {
public:
void show() override {
cout << "Derived class" << endl;
}
};
int main() {
Base* basePtr;
Derived derivedObj;
basePtr = &derivedObj;
basePtr->show(); // 调用Derived::show,通过动态绑定实现
return 0;
}
虚函数的实现原理
当一个类包含虚函数时,编译器为该类创立虚函数表(vtable),表中存放该类虚函数的指针。类的每个对象保存一个指向其虚函数表的虚指针(vptr)。通过该虚指针,可以在运行时动态地调用正确的函数实现。
(2)纯虚函数(Pure Virtual Function):
纯虚函数没有函数体,需要在基类中声明,并在派生类中实现。含有纯虚函数的类称为抽象类,不能被实例化。
#include<iostream>
using namespace std;
class Base {
public:
virtual void show() = 0; // 纯虚函数
};
class Derived : public Base {
public:
void show() override {
cout << "Derived class implementing pure virtual function" << endl;
}
};
int main() {
Derived derivedObj;
Base* basePtr = &derivedObj;
basePtr->show(); // 调用Derived::show
return 0;
}
总结
- 静态多态(重载和模板):在编译时确定调用的函数,通过参数类型和数量(重载)或模板实例化来实现。
- 动态多态(覆盖和虚函数):在运行时动态决定调用的函数,通过虚函数和虚函数表实现。虚函数可以在派生类中覆盖,纯虚函数强制派生类实现。
以上的概念为C++编程中的多态提供了灵活而强大的功能,允许同一接口在不同上下文中表现出不同的行为。