Maison  >  Article  >  développement back-end  >  Quelles sont les applications des pointeurs de fonctions C++ dans les méthodes virtuelles et les tables virtuelles ?

Quelles sont les applications des pointeurs de fonctions C++ dans les méthodes virtuelles et les tables virtuelles ?

王林
王林original
2024-04-17 18:00:021087parcourir

Les pointeurs de fonction C++ sont utilisés dans les méthodes virtuelles pour stocker des pointeurs vers des implémentations de méthodes remplacées dans des classes dérivées, et dans des tables virtuelles pour initialiser des tables virtuelles et stocker des pointeurs vers des implémentations de méthodes virtuelles, obtenant ainsi un polymorphisme d'exécution et permettant aux classes dérivées de réécrire des méthodes virtuelles. méthodes dans la classe de base et appelez l’implémentation correcte en fonction du type réel de l’objet au moment de l’exécution.

C++ 函数指针在虚拟方法和虚表中的应用有哪些?

Pointeur de fonction C++ : application des méthodes virtuelles et des tables virtuelles

En C++, les pointeurs de fonction jouent un rôle essentiel dans l'implémentation de méthodes virtuelles et la maintenance des tables virtuelles. Cet article approfondira ces applications et approfondira leur compréhension à travers des cas pratiques.

Méthodes virtuelles

Les méthodes virtuelles sont des fonctions membres déclarées dans la classe de base et remplacées par la classe dérivée. Lorsqu'une méthode virtuelle est appelée via un pointeur de classe de base, l'implémentation de la classe dérivée est appelée en fonction du type réel de l'objet d'exécution.

Afin d'implémenter des méthodes virtuelles, le compilateur créera une table de fonctions virtuelles (vtable) pour chaque classe de base, qui stocke des pointeurs vers chaque implémentation de méthode virtuelle. Lorsqu'une méthode virtuelle est appelée, le compilateur utilise la vtable de l'objet pour rechercher et appeler l'implémentation correcte.

Application des pointeurs de fonction dans les méthodes virtuelles

Les pointeurs de fonction sont utilisés pour stocker des pointeurs vers les implémentations de méthodes virtuelles dans les tables virtuelles. Le compilateur alloue une entrée vtable pour chaque méthode virtuelle et la remplit avec un pointeur de fonction pointant vers l'implémentation de la méthode.

Exemple :

class Base {
public:
    virtual void print() {
        cout << "Base::print" << endl;
    }
};

class Derived : public Base {
public:
    virtual void print() override {
        cout << "Derived::print" << endl;
    }
};

int main() {
    Base* base = new Derived;
    base->print(); // 输出 "Derived::print"
}

Dans cet exemple, le compilateur crée une table virtuelle contenant deux entrées. La première entrée pointe vers l'implémentation de la méthode print() dans la classe de base Base, et la seconde entrée pointe vers le Derived remplacé dans l'implémentation de la méthode de classe dérivée code>print(). Lors de l'exécution de base->print(), le compilateur utilise la vtable pour obtenir le pointeur de fonction approprié et appelle l'implémentation correspondante. Baseprint() 方法的实现,第二个条目指向派生类 Derived 中重写的 print() 方法的实现。当执行 base->print() 时,编译器使用 vtable 获取恰当的函数指针并调用对应的实现。

虚表

虚表是一种数据结构,用于存储指向虚方法实现的函数指针。虚表中的每个条目对应于基类中声明的一个虚方法。

函数指针在虚表中的应用

函数指针用于初始化虚表并存储指向虚拟方法实现的指针。当编译器检测到一个类包含虚方法时,它会为该类生成一个虚表。虚表中每个条目的类型都是对应方法返回类型的函数指针。

在前面的示例中,编译器会为基类 Base 生成一个包含两个条目的虚表:

vtable[Base] = {
    Base::print,
    Derived::print
};

实战案例

让我们通过一个现实世界的例子进一步了解函数指针在虚拟方法和虚表中的应用。让我们创建一个简单的图形绘制库:

class Shape {
public:
    virtual void draw() = 0;
};

class Circle : public Shape {
public:
    virtual void draw() override {
        cout << "Drawing a circle..." << endl;
    }
};

class Square : public Shape {
public:
    virtual void draw() override {
        cout << "Drawing a square..." << endl;
    }
};

int main() {
    vector<Shape*> shapes;
    shapes.push_back(new Circle);
    shapes.push_back(new Square);

    for (auto shape : shapes) {
        shape->draw();
    }
}

在这个示例中,Shape 类是基类,而 CircleSquare 是派生类。draw() 方法是一个虚拟方法,由每个派生类重写。编译器为 Shape 类创建了一个虚表,其中包含指向每个派生类 draw() 方法实现的函数指针。

当调用 shape->draw() 时,编译器会使用对象的 vtable 获取恰当的函数指针并调用正确的实现。这让我们能够通过一个统一的 Shape

🎜Table virtuelle🎜🎜🎜Une table virtuelle est une structure de données utilisée pour stocker des pointeurs de fonction pointant vers des implémentations de méthodes virtuelles. Chaque entrée de la table virtuelle correspond à une méthode virtuelle déclarée dans la classe de base. 🎜🎜🎜Application des pointeurs de fonction dans les tables virtuelles🎜🎜🎜Les pointeurs de fonction sont utilisés pour initialiser des tables virtuelles et stocker des pointeurs vers des implémentations de méthodes virtuelles. Lorsque le compilateur détecte qu'une classe contient des méthodes virtuelles, il génère une table virtuelle pour la classe. Le type de chaque entrée de la table virtuelle est un pointeur de fonction correspondant au type de retour de la méthode. 🎜🎜Dans l'exemple précédent, le compilateur générera une table virtuelle contenant deux entrées pour la classe de base Base : 🎜rrreee🎜🎜Cas pratique🎜🎜🎜Allons plus loin avec un exemple concret Comprendre l'utilisation des pointeurs de fonction dans les méthodes virtuelles et les tables virtuelles. Créons une bibliothèque de dessins de formes simple : 🎜rrreee🎜Dans cet exemple, la classe Shape est la classe de base, tandis que Circle et Square sont Derived classe. La méthode draw() est une méthode virtuelle et est remplacée par chaque classe dérivée. Le compilateur crée une table virtuelle pour la classe Shape qui contient des pointeurs de fonction vers l'implémentation de chaque classe dérivée de la méthode draw(). 🎜🎜Lorsque shape->draw() est appelé, le compilateur utilise la table virtuelle de l'objet pour obtenir le pointeur de fonction approprié et appelle l'implémentation correcte. Cela nous permet de dessiner différents types de formes via une interface Shape unifiée sans avoir besoin de conversions explicites. 🎜

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn