C++ moderne et alternatives en C

Le polymorphisme en C++ et les tables de pointeurs de fonction en C

Dans cette leçon, vous allez appeler la même opération sur plusieurs types d'objets, avec des fonctions virtuelles en C++ et des pointeurs de fonction en C.

Introduction

Le polymorphisme dynamique (dynamic polymorphism) permet au code d'appeler une opération commune, comme le calcul d'une aire, tandis que chaque type d'objet décide lui-même comment la réaliser. C++ le prend en charge directement avec les fonctions virtuelles (virtual functions), et en C on peut l'imiter avec des pointeurs de fonction.

Points importants

  • Comprenez comment on fait en C avant d'apprendre les abstractions du C++.
  • Exprimez la possession des ressources avec RAII et la sémantique de valeur (value semantics).
  • Préférez les outils sûrs du point de vue des types du C++ aux macros et aux conversions de type.

Exemples de code C et C++

C
Exécuter →
main.c
#include <stdio.h>

typedef struct Shape Shape;
struct Shape {
    double value;
    double (*area)(const Shape *shape);
};

double square_area(const Shape *shape) {
    return shape->value * shape->value;
}

int main(void) {
    Shape square = {4.0, square_area};
    printf("area=%.1f\n", square.area(&square));
}
Résultat de l’exécution
area=16.0
C++
Exécuter →
main.cpp
#include <iostream>

struct Shape {
    virtual double area() const = 0;
    virtual ~Shape() = default;
};

struct Square : Shape {
    double side;

    explicit Square(double value) : side(value) {}
    double area() const override { return side * side; }
};

int main() {
    Square square(4);
    const Shape& shape = square;
    std::cout << "area=" << shape.area() << '\n';
}
Résultat de l’exécution
area=16

Comparaison entre C et C++

En C, struct Shape contient un pointeur de fonction area, et chaque forme y associe sa propre fonction de calcul d'aire, comme square_area. En C++, les fonctions virtuelles créent automatiquement ce même mécanisme de choix. La classe de base doit aussi avoir un destructeur virtuel (virtual destructor) pour que la suppression d'un objet via un pointeur de classe de base soit sûre.

C

C utilise des conventions de nommage, des callbacks, des macros et des struct de contexte.

C++

C++ offre des abstractions à la portée bien délimitée, sûres pour les types et généralement sans coût supplémentaire à l'exécution.

Exercices d'approfondissement

Exécutez les deux versions, puis modifiez le code pour observer la différence de sécurité qu'apporte chaque langage.

  • Écrivez d'abord le mécanisme en C, puis utilisez la fonctionnalité équivalente du C++.
  • Remplacez la libération manuelle des ressources par RAII.
  • Vérifiez si la fonctionnalité provoque des allocations mémoire ou des appels de fonctions virtuelles.

S'entraîner avec un défi

Utilisez le contenu de cette leçon pour résoudre un vrai problème. Chaque défi s'exécute dans le navigateur, avec des tests instantanés et une revue par l'IA.

Tous les défis