
在C++中,虚函数表(vtable)和虚指针(vptr)是实现多态性的关键机制。
每个使用虚函数的类都有一个虚函数表(vtable)。vtable是一个包含指向类虚函数的指针的数组。每个对象都有一个虚指针(vptr),指向其类的vtable。当调用对象的虚函数时,实际上是通过vptr和vtable来动态确定要调用哪个函数。
示例代码:
- #include <iostream>
- using namespace std;
-
- class Base {
- public:
- virtual void show() { cout << "Base class show" << endl; }
- };
-
- class Derived : public Base {
- public:
- void show() override { cout << "Derived class show" << endl; }
- };
-
- int main() {
- Base *bptr;
- Derived d;
- bptr = &d;
-
- // 动态调用正确的函数(Derived::show)
- bptr->show();
-
- return 0;
- }
C++中的多态性允许通过基类指针调用派生类的函数。这是通过虚函数(在基类中声明为virtual)和自动维护的vptr和vtable实现的。
示例代码:
- #include
- using namespace std;
-
- class Animal {
- public:
- virtual void speak() { cout << "Some animal sound" << endl; }
- };
-
- class Dog : public Animal {
- public:
- void speak() override { cout << "Woof" << endl; }
- };
-
- class Cat : public Animal {
- public:
- void speak() override { cout << "Meow" << endl; }
- };
-
- void makeAnimalSpeak(Animal* animal) {
- animal->speak();
- }
-
- int main() {
- Dog dog;
- Cat cat;
-
- makeAnimalSpeak(&dog);
- makeAnimalSpeak(&cat);
-
- return 0;
- }
使用虚析构函数确保当通过基类指针删除派生类对象时,可以正确地调用派生类的析构函数,避免资源泄露。
示例代码:
- #include <iostream>
- using namespace std;
-
- class Base {
- public:
- virtual ~Base() { cout << "Base destructor" << endl; }
- };
-
- class Derived : public Base {
- public:
- ~Derived() { cout << "Derived destructor" << endl; }
- };
-
- int main() {
- Base *b = new Derived();
- delete b; // 正确调用Derived析构函数,然后是Base析构函数
- return 0;
- }
纯虚函数是一种没有实现的虚函数,其唯一目的是在派生类中进行重写。包含纯虚函数的类称为抽象类,不能实例化。
示例代码:
- #include <iostream>
- using namespace std;
-
- class Shape {
- public:
- virtual void draw() = 0; // 纯虚函数
- };
-
- class Circle : public Shape {
- public:
- void draw() override { cout << "Drawing Circle" << endl; }
- };
-
- int main() {
- // Shape s; // 错误:不能实例化抽象类
- Circle c;
- c.draw(); // 正确:调用Circle::draw
- return 0;
- }
虚函数可以在派生类中被重写,这是多态的基础。重写是指派生类提供一个与基类虚函数签名完全相同的函数实现。与之相对的,重载是在同一个类中创建相同名称但参数列表不同的函数。
示例代码:
- #include <iostream>
- using namespace std;
-
- class Base {
- public:
- virtual void func() { cout << "Base func()" << endl; }
- virtual void func(int x) { cout << "Base func(int)" <<
-
- endl; }
- };
-
- class Derived : public Base {
- public:
- void func() override { cout << "Derived func()" << endl; }
- // 注意:这不是重写,因为参数列表不同,这是重载
- void func(int x) override { cout << "Derived func(int)" << endl; }
- };
-
- int main() {
- Derived d;
- d.func(); // 调用Derived::func()
- d.func(10); // 调用Derived::func(int)
-
- return 0;
- }