C++ 98/03 应该学习哪些知识11

文章介绍了虚函数和纯虚函数的概念,虚函数用于运行时动态绑定,通过虚函数表(vtable)和虚表指针(vptr)实现。纯虚函数定义接口,强制派生类实现。示例代码展示了如何使用虚函数和纯虚函数实现多态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

虚函数与纯虚函数、虚函数实现机制、虚函数表

虚函数和纯虚函数

虚函数是在基类中声明为virtual的成员函数,它可以被派生类重写,让程序在运行时根据实际对象类型来调用正确的函数实现。纯虚函数是在基类中声明为virtual并且没有实现的成员函数,它需要在派生类中被实现,可以用来定义接口或者让派生类必须实现某些函数。

虚函数实现机制

当一个类中声明了虚函数时,编译器会为其生成一个虚函数表(vtable),用于存储每个虚函数的地址。在创建类的对象时,编译器会在对象的内存布局中添加一个指向虚函数表的指针,这个指针被称为虚表指针(vptr)。当调用虚函数时,程序会根据对象的vptr找到对应的虚函数表,然后根据函数在表中的位置找到实际的函数实现。

虚函数表

虚函数表是一个数组,其中每个元素是一个指向虚函数实现的指针。它由编译器在编译时自动生成,并且在程序运行时被加载到内存中。每个类只有一个虚函数表,它包含了该类及其所有基类的虚函数。

下面是一个简单的例子,演示了虚函数和纯虚函数的使用以及虚函数表的实现机制:

#include <iostream>
using namespace std;

class Animal {
public:
    virtual void speak() {
        cout << "I am an animal." << endl;
    }
    virtual void eat() = 0; // 纯虚函数
};

class Cat : public Animal {
public:
    void speak() override {
        cout << "I am a cat." << endl;
    }
    void eat() override {
        cout << "Cat eats fish." << endl;
    }
};

class Dog : public Animal {
public:
    void speak() override {
        cout << "I am a dog." << endl;
    }
    void eat() override {
        cout << "Dog eats bone." << endl;
    }
};

int main() {
    Animal* animalPtr;
    Cat cat;
    Dog dog;

    animalPtr = &cat;
    animalPtr->speak(); // 输出 "I am a cat."
    animalPtr->eat(); // 输出 "Cat eats fish."

    animalPtr = &dog;
    animalPtr->speak(); // 输出 "I am a dog."
    animalPtr->eat(); // 输出 "Dog eats bone."

    return 0;
}

在这个例子中,Animal是一个基类,它声明了一个虚函数speak和一个纯虚函数eat。Cat和Dog都是Animal的派生类,它们分别重写了speak和eat函数。在程序中,animalPtr是一个指向Animal对象的指针,通过将它指向Cat和Dog对象,可以让程序根据实际对象类型来调用正确的函数实现。虚函数表和vptr的实现细节由编译器实现,并且可能因编译器而异。

在这个例子中,每个类都有一个虚函数表,其中Animal的虚函数表包含了speak和eat函数的地址,Cat和Dog的虚函数表分别包含了它们重写的speak和eat函数的地址。在程序中,当animalPtr指向Cat对象时,调用speak函数时会先根据vptr找到Cat对象的虚函数表,然后根据表中speak函数在表中的位置找到实际的函数实现。同样的,当animalPtr指向Dog对象时,调用speak函数时会根据vptr找到Dog对象的虚函数表,并根据表中speak函数在表中的位置找到实际的函数实现。虚函数和虚函数表的实现机制为多态提供了基础,可以让程序在运行时根据实际对象类型来调用正确的函数实现。

总结

虚函数和纯虚函数是面向对象编程中重要的概念,它们为多态提供了基础。虚函数通过虚函数表和vptr实现了运行时动态绑定,可以让程序根据实际对象类型来调用正确的函数实现。纯虚函数可以用来定义接口或者让派生类必须实现某些函数。虚函数和纯虚函数的实现机制可以让程序更加灵活和可扩展,提高代码的复用性和可维护性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

五百五。

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值