C++多态机制实现原理
虚函数基础
虚函数是实现多态的核心机制,仅能在继承体系中声明。其语法特征是在成员函数前添加virtual关键字:
在继承体系中需区分两个概念:
- 隐藏:基类与派生类函数名相同即触发
- 重写:需满足函数名、返回值类型、参数类型完全一致(协变除外)
多态实现机制
多态本质是同一行为在不同对象上产生不同结果,实现代码如下:
class Animal {
public:
virtual void Speak() {
cout << "Animal sound" << endl;
}
};
class Dog : public Animal {
public:
virtual void Speak() override {
cout << "Woof!" << endl;
}
};
class Cat : public Animal {
public:
virtual void Speak() override {
cout << "Meow~" << endl;
}
};
void MakeSound(Animal& a) {
a.Speak();
}
int main() {
Dog d;
Cat c;
MakeSound(d); // 输出: Woof!
MakeSound(c); // 输出: Meow~
}
多态生效需同时满足:
- 虚函数完成重写
- 通过基类指针或引用调用
协变特例
当返回值为继承关系的指针/引用时,函数签名可不同:
虚函数表原理
编译器为包含虚函数的类生成虚表(vtable),其本质是函数指针数组:
- 基类对象存储基类虚表地址
- 派生类重写虚函数时,替换虚表对应项
- 未重写时继承基类虚函数项
绑定机制对比
| 绑定类型 | 适用场景 | 确定时机 |
|---|---|---|
| 静态绑定 | 普通成员函数 | 编译期 |
| 动态绑定 | 虚函数调用 | 运行期 |
析构函数特例
基类析构函数必须声明为虚函数:
class Base {
public:
virtual ~Base() { /* 基类资源释放 */ }
};
class Derived : public Base {
public:
~Derived() override {
/* 派生类专用资源释放 */
}
};
// 正确释放
Base* obj = new Derived();
delete obj; // 调用Derived::~Derived()
编译器将析构函数统一命名为destructor(),虚析构保证正确调用派生类析构函数
抽象类应用
含纯虚函数的类称为抽象类(不可实例化):
class DataExporter {
public:
virtual void Export() = 0; // 纯虚函数
};
class CSVExporter : public DataExporter {
public:
void Export() override {
// CSV导出实现
}
};
class JSONExporter : public DataExporter {
public:
void Export() override {
// JSON导出实现
}
};
// 策略模式应用
class ReportGenerator {
public:
void SetExporter(DataExporter* e) {
exporter = e;
}
void Generate() {
// 生成报告
exporter->Export();
}
private:
DataExporter* exporter;
};
关键细节
- 构造函数中调用虚函数执行静态绑定
- 虚函数重写不改变函数签名
virtual关键字仅用于声明static与virtual不能共用