C&C++快速入门
21、多态
1、课程目标
- 理解多态的概念
- 掌握虚函数和纯虚函数
- 理解虚函数表(vtable)
- 掌握抽象类和接口
2、名词解释
| 术语 | 说明 |
|---|---|
| 多态 | 同一接口的不同实现 |
| 虚函数 | virtual关键字修饰,可被重写 |
| 纯虚函数 | = 0的虚函数,必须重写 |
| 抽象类 | 包含纯虚函数的类 |
| vtable | 虚函数表,存储虚函数地址 |
| vptr | 指向vtable的指针 |
| 重写 | 子类重新实现父类虚函数 |
3、代码实现
1. 虚函数基础
#include <iostream>
using namespace std;
class Shape {
public:
virtual void Draw() {
cout << "Drawing Shape" << endl;
}
virtual ~Shape() {
cout << "~Shape" << endl;
}
};
class Circle : public Shape {
public:
void Draw() override {
cout << "Drawing Circle" << endl;
}
~Circle() {
cout << "~Circle" << endl;
}
};
class Rectangle : public Shape {
public:
void Draw() override {
cout << "Drawing Rectangle" << endl;
}
};
int main() {
cout << "=== 多态 ===" << endl << endl;
Shape* shapes[] = {
new Circle(),
new Rectangle(),
new Shape()
};
// 多态调用
for (int i = 0; i < 3; i++) {
shapes[i]->Draw(); // 根据实际类型调用
}
cout << "\n释放对象:" << endl;
for (int i = 0; i < 3; i++) {
delete shapes[i];
}
return 0;
}
2. 抽象类和接口
#include <iostream>
using namespace std;
// 抽象类(接口)
class IPlugin {
public:
virtual void Initialize() = 0; // 纯虚函数
virtual void Execute() = 0;
virtual void Cleanup() = 0;
virtual ~IPlugin() {}
};
class LoggerPlugin : public IPlugin {
public:
void Initialize() override {
cout << "Logger: Initialize" << endl;
}
void Execute() override {
cout << "Logger: Logging..." << endl;
}
void Cleanup() override {
cout << "Logger: Cleanup" << endl;
}
};
class NetworkPlugin : public IPlugin {
public:
void Initialize() override {
cout << "Network: Initialize" << endl;
}
void Execute() override {
cout << "Network: Connecting..." << endl;
}
void Cleanup() override {
cout << "Network: Cleanup" << endl;
}
};
void RunPlugin(IPlugin* plugin) {
plugin->Initialize();
plugin->Execute();
plugin->Cleanup();
}
int main() {
cout << "=== 抽象类 ===" << endl << endl;
LoggerPlugin logger;
NetworkPlugin network;
cout << "运行Logger:" << endl;
RunPlugin(&logger);
cout << "\n运行Network:" << endl;
RunPlugin(&network);
return 0;
}
3. 虚函数表查看
#include <iostream>
#include <windows.h>
using namespace std;
class Base {
public:
virtual void Func1() { cout << "Base::Func1" << endl; }
virtual void Func2() { cout << "Base::Func2" << endl; }
};
int main() {
cout << "=== 虚函数表 ===" << endl << endl;
Base obj;
// 获取vptr (对象的第一个成员)
void** vptr = *(void***)&obj;
cout << "对象地址: " << &obj << endl;
cout << "vtable地址: " << vptr << endl;
cout << "Func1地址: " << vptr[0] << endl;
cout << "Func2地址: " << vptr[1] << endl;
// 通过vtable调用
cout << "\n通过vtable调用:" << endl;
typedef void (*VFunc)(Base*);
((VFunc)vptr[0])(&obj);
((VFunc)vptr[1])(&obj);
return 0;
}
4、课后作业
4.1、作业1:实现动物类层次
实现Animal基类和Dog、Cat子类,使用多态。
4.2、作业2:解析vtable
手动解析一个类的虚函数表并调用其中的函数。