在 C++ 中,虚函数(virtual function)是实现多态的一种机制。通过虚函数,可以在派生类中重写(override)基类中的函数,从而在运行时根据对象的实际类型调用相应的函数。以下是关于 C++ 中虚函数的详细介绍和示例。
1. 基本概念
- 虚函数:在基类中声明为
virtual
的成员函数。虚函数允许派生类重写该函数,从而实现多态。
- 纯虚函数:在基类中声明为
virtual
并且没有实现的函数,形式为 virtual 返回类型 函数名() = 0;
。含有纯虚函数的类称为抽象类,不能实例化。
- 多态:通过基类指针或引用调用虚函数时,实际调用的是派生类中重写的函数,而不是基类中的函数。
2. 虚函数的声明和使用
声明虚函数
在基类中声明虚函数:
1 2 3 4 5 6
| class Base { public: virtual void display() { std::cout << "Base class display function" << std::endl; } };
|
派生类中重写虚函数
在派生类中重写基类的虚函数:
1 2 3 4 5 6
| class Derived : public Base { public: void display() override { std::cout << "Derived class display function" << std::endl; } };
|
3. 多态的实现
通过基类指针或引用调用虚函数:
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
| #include <iostream>
class Base { public: virtual void display() { std::cout << "Base class display function" << std::endl; } };
class Derived : public Base { public: void display() override { std::cout << "Derived class display function" << std::endl; } };
int main() { Base baseObj; Derived derivedObj;
Base* basePtr = &baseObj; Base* derivedPtr = &derivedObj;
basePtr->display(); derivedPtr->display();
return 0; }
|
4. 纯虚函数和抽象类
声明纯虚函数
在基类中声明纯虚函数:
1 2 3 4
| class Base { public: virtual void display() = 0; };
|
派生类中实现纯虚函数
在派生类中实现基类的纯虚函数:
1 2 3 4 5 6
| class Derived : public Base { public: void display() override { std::cout << "Derived class display function" << std::endl; } };
|
5. 构造函数和析构函数中的虚函数
- 构造函数:虚函数在构造函数中不具有多态性,即在构造函数中调用虚函数时,只会调用当前类的虚函数,不会调用派生类的虚函数。
- 析构函数:虚函数在析构函数中具有多态性,因此基类的析构函数通常声明为虚函数,以确保派生类的析构函数也能被调用。
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>
class Base { public: virtual ~Base() {} virtual void display() { std::cout << "Base class display function" << std::endl; } };
class Derived : public Base { public: ~Derived() {} void display() override { std::cout << "Derived class display function" << std::endl; } };
int main() { Base* basePtr = new Derived(); basePtr->display(); delete basePtr;
return 0; }
|
6. 虚函数表(VTable)
C++ 编译器在内部使用虚函数表(Virtual Table, VTable)来实现虚函数的多态调用。每个包含虚函数的类都有一个虚函数表,表中存放了该类所有虚函数的地址。每个对象都有一个指向其类的虚函数表的指针(vptr),通过 vptr 可以找到对应的虚函数地址。