Maison >développement back-end >C++ >Quelle est la différence entre les fonctions virtuelles et virtuelles pures dans la programmation orientée objet ?

Quelle est la différence entre les fonctions virtuelles et virtuelles pures dans la programmation orientée objet ?

DDD
DDDoriginal
2024-12-26 02:21:10754parcourir

What's the Difference Between Virtual and Pure Virtual Functions in Object-Oriented Programming?

Comprendre les fonctions virtuelles et virtuelles pures

Les fonctions virtuelles jouent un rôle crucial dans la programmation orientée objet en permettant le polymorphisme d'exécution. Telle que définie par Wikipédia, une fonction virtuelle est une méthode ou une fonction remplaçable qui permet une répartition dynamique. Cela signifie que la fonction spécifique à exécuter est déterminée en fonction du type d'objet au moment de l'exécution, plutôt qu'au moment de la compilation.

Contrairement aux fonctions non virtuelles, lorsqu'une fonction virtuelle est remplacée dans une classe dérivée , la version définie dans la classe la plus dérivée est utilisée dans toute la hiérarchie des classes. Cela garantit que l'implémentation la plus spécifique de la fonction est toujours utilisée.

Les fonctions virtuelles pures, également appelées méthodes virtuelles pures, poussent ce concept plus loin. Ce sont des fonctions virtuelles qui doivent être implémentées dans une classe dérivée si cette classe n'est pas abstraite. En tant que telle, une fonction virtuelle pure impose effectivement la présence d'un comportement particulier dans les classes dérivées.

Les classes abstraites sont celles qui contiennent une ou plusieurs fonctions virtuelles pures. De telles classes ne peuvent pas être instanciées directement ; à la place, une classe dérivée fournissant des implémentations pour toutes les fonctions virtuelles pures doit être utilisée.

Pour illustrer les différences entre les fonctions virtuelles et virtuelles pures, considérons le C suivant code :

Base.hpp:

struct Base {
    virtual ~Base() = default;
    virtual void foo() {
        std::cout << "Base::Foo" << std::endl;
    }
};

Derived.hpp:

struct Derived : public Base {
    void foo() override {
        std::cout << "Derived::Foo" << std::endl;
    }
};

main .cpp :

int main() {
    Base base;
    base.foo();  // Calls Base::Foo

    Derived derived;
    derived.foo();  // Calls Derived::Foo

    Base* derived_as_base = &derived;
    derived_as_base->foo();  // Calls Derived::Foo (due to dynamic dispatch)
}

Dans ce code, la classe Base contient un fonction virtuelle foo qui imprime "Base :: Foo". La classe Derived remplace cette fonction pour imprimer « Derived :: Foo ». Lorsqu'un objet Base appelle foo, le résultat est "Base::Foo". Cependant, lorsqu'un objet Derived (accessible en tant que pointeur de base) appelle foo, le résultat est "Derived::Foo" en raison de la répartition dynamique.

Maintenant, considérons un pur virtuel fonction :

PureBase.hpp :

struct PureBase {
    virtual ~PureBase() = default;
    virtual void foo() = 0;  // Pure virtual function
};

PureDerived.hpp :

struct PureDerived : public PureBase {
    void foo() override {
        std::cout << "PureDerived::Foo" << std::endl;
    }
};

Dans ce code, la classe PureBase contient une fonction virtuelle pure foo qui n'est pas définie dans la classe de base. Par conséquent, la classe PureBase est abstraite car il lui manque une implémentation complète.

PureMain.cpp :

int main() {
    // error: cannot declare variable 'pureBase' to be of abstract type 'PureBase'
    // PureBase pureBase;
    // pureBase.foo();

    PureDerived pureDerived;
    pureDerived.foo();  // Calls PureDerived::Foo
}

Dans cet exemple, tenter d'instancier une classe PureBase L'objet entraîne directement une erreur du compilateur. Cependant, la création d'un objet PureDerived est autorisée car elle fournit une implémentation pour la fonction foo.

Pour résumer, les fonctions virtuelles fournissent une répartition dynamique et peuvent être remplacées dans les classes dérivées. Les fonctions virtuelles pures, en revanche, doivent être implémentées dans des classes dérivées et appliquer des comportements spécifiques. Ensemble, ces concepts jouent un rôle essentiel dans l'activation des fonctionnalités polymorphes dans la programmation orientée objet.

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