Maison > développement back-end > C++ > Pourquoi C ne prend-il pas en charge la covariance des modèles et comment pouvons-nous résoudre les problèmes de sécurité des types qui en résultent lorsque nous travaillons avec des modèles polymorphes ?

Pourquoi C ne prend-il pas en charge la covariance des modèles et comment pouvons-nous résoudre les problèmes de sécurité des types qui en résultent lorsque nous travaillons avec des modèles polymorphes ?

Patricia Arquette
Libérer: 2024-10-28 08:14:02
original
578 Les gens l'ont consulté

Why doesn't C   support template covariance, and how can we address the resulting type safety issues when working with polymorphic templates?

Modèles et polymorphisme en C

Considérez la structure de classe suivante :

<code class="cpp">class Interface {
  // ...
};

class Foo : public Interface {
  // ...
};

template <class T>
class Container {
  // ...
};</code>
Copier après la connexion

Un constructeur d'une autre classe Bar est défini comme :

<code class="cpp">Bar(const Container<Interface>& bar) {
  // ...
}</code>
Copier après la connexion

Cependant, lorsque vous tentez d'appeler le constructeur comme suit :

<code class="cpp">Container<Foo> container();

Bar *temp = new Bar(container);</code>
Copier après la connexion

nous rencontrons une erreur "aucune fonction de correspondance".

Polymorphisme dans les modèles

Le concept de polymorphisme dans les modèles, ou covariance des modèles, impliquerait que si la classe B hérite de la classe A, alors T hérite également de T. Cependant, ce n'est pas le cas en C ou dans d'autres langages comme Java ou C#.

Raison du manque de covariance du modèle

L'absence de covariance du modèle est justifiée par le besoin de maintenir la sécurité du type. Prenons l'exemple suivant :

<code class="cpp">// Class hierarchy
class Fruit {...};
class Apple : public Fruit {...};
class Orange : public Fruit {...};

// Template instantiation using std::vector
int main() {
  std::vector<Apple> apple_vec;
  apple_vec.push_back(Apple()); // Valid

  // With covariance, the following would be allowed
  std::vector<Fruit>& fruit_vec = apple_vec;

  // Adding an Orange to the vector
  fruit_vec.push_back(Orange());

  // Incorrect addition of an orange to an apple vector
}</code>
Copier après la connexion

Cela démontre le potentiel de comportement dangereux si les modèles étaient covariants. Par conséquent, T et T sont considérés comme des types complètement distincts, quelle que soit la relation entre A et B.

Résoudre le problème

Une approche pour résoudre le problème en Java et C# consiste à utiliser des types limités caractères génériques et contraintes, respectivement :

<code class="java">Bar(Container<? extends Interface) {...}
Copier après la connexion
<code class="csharp">Bar<T>(Container<T> container) where T : Interface {...}</code>
Copier après la connexion

En C , la bibliothèque Boost Concept Check peut fournir des fonctionnalités similaires. Cependant, l'utilisation d'une simple assertion statique peut être une solution plus pratique pour le problème spécifique rencontré :

<code class="cpp">static_assert(std::is_base_of<Interface, Foo>::value, "Container must hold objects of type Interface or its derived classes.");</code>
Copier après la connexion

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!

source:php.cn
Déclaration de ce site Web
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
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal