Extension de bibliothèques en C ++

Est-il possible d’étendre une classe à partir d’une bibliothèque C ++ sans le code source? L’en-tête serait-il suffisant pour vous permettre d’utiliser l’inheritance? Je viens d’apprendre le C ++ et j’entre dans la théorie. Je voudrais tester cela, mais je ne sais pas comment.

Réponse courte OUI, vous le pouvez définitivement.

Réponse longue : AVERTISSEMENT: le texte suivant peut blesser les intégristes sensibles à la POO. Si vous croyez ou retenez en être un, tenez-vous à l’écart de cette réponse: la vie sera plus facile pour vous et pour tous

Permettez-moi de révéler un secret: le code STL n’est rien de plus que du code C ++ standard fourni avec des en-têtes et des bibliothèques, exactement comme votre code peut, et probablement, le faire. Les auteurs de STL ne sont que des programmeurs LIKE YOU. Ils ne sont pas spéciaux du tout pour le compilateur. Thay n’a aucun super pouvoir à son égard. Ils sont assis sur leurs canvasttes , exactement comme vous sur les vôtres, pour faire exactement ce que vous faites. Ne les abusez pas trop.

Le code STL suit exactement les mêmes règles que votre propre code écrit: ce qui est remplacé sera appelé à la place de la base: toujours s’il est virtuel, et uniquement en fonction du type statique de son pointeur de renvoi s’il n’est pas virtuel, comme tous les autres. morceau de code C ++. Ni plus ni moins.

L’important est de ne pas subvertir les problèmes de conception en respectant la convention et la sémantique de nom STL, de sorte que toute utilisation ultérieure de votre code ne déroutera pas l’attente des autres, y compris vous-même, en lisant votre code après 10 ans et en ne rappelant plus certaines décisions.

Par exemple, le fait de remplacer std::exception::what() doit renvoyer une chaîne C persistante explicative (comme le dit la documentation STL) et ne pas append d’autres actions inattendues.

En outre, il est nécessaire de remplacer les stream ou les opérateurs de streaming en considérant l’ensemble du projet (avez-vous vraiment besoin de remplacer le stream ou simplement le filtre à vapeur ou simplement d’append une facette spécifique à l’ environnement local imprégné?): En d’autres termes, étudiez non seulement classe “mais la conception de tout son” monde “pour bien comprendre comment il fonctionne avec ce qui est autour.

Dernier point, mais non des moindres, l’un des aspects les plus controversés concerne les conteneurs et tout ce qui n’a pas de destructeurs virtuels.

Mon opinion est que le bruit autour de la “règle classique de la POO: Ne dérivez pas ce qui n’a pas de destructeur virtuel” est trop gonflé: ne vous attendez pas à ce qu’une cow devienne un horse simplement parce que vous placez une saddle dessus.

Si vous avez vraiment besoin d’une classe qui gère une séquence de caractères avec exactement la même interface que std :: ssortingng et qui est capable de convertir implicitement en std :: ssortingng et qui a quelque chose de plus, vous avez deux possibilités:

  • faites ce que les bonnes filles font de bien, intégrez std:ssortingng et réécrivez toutes ses 112 (oui: elles sont plus de 100) avec des méthodes qui ne font que les appeler et vous assurer que vous venez toujours vierge au mariage avec un autre bon le code du programmeur, ou …
  • Après avoir découvert que cela prend environ 30 ans et que vous risquez de devenir vierge à 40 ans, aucun bon programmeur ne s’intéresse, soyez plus pratique, sacrifiez votre virginité et dérivez std::ssortingng . La seule chose que vous perdrez est votre possibilité d’épouser un intégrististe. Et vous pouvez même découvrir que ce n’est pas nécessairement un problème: vous évitez même le risque d’être tué par lui!

La seule chose que vous devez faire attention, c’est que, étant std::ssortingng non polymorphe, votre dérivation le fera en tant que tel, alors ne vous attendez pas à std::ssortingng* ou std::ssortingng& référant votre yourssortingng d’appel à vos méthodes, y compris le destructeur, ce n’est aucun respect particulier de toutes les autres méthodes; il suffit de suivre exactement les mêmes règles. Mais … hé, si vous intégrez et écrivez un opérateur de conversion implicite, vous obtiendrez exactement ce résultat, ni plus ni moins!

La règle est simple: ne faites pas de votre destructeur virtuel et ne prétendez pas que le “principe de substitution de la POO” fonctionne avec quelque chose qui n’est pas conçu pour la POO et tout ira bien.

Avec tous les requêtes intégristes de la programmation orientée object pacem leur sumil endormi, votre code fonctionnera, alors qu’ils réécrivent encore la méthode 100+ std :: ssortingng juste pour l’intégrer.

Oui, la déclaration de la classe suffit à en dériver.

Le rest du code sera récupéré lorsque vous établissez un lien avec la bibliothèque.

Oui, vous pouvez étendre les classes dans la bibliothèque standard C ++. Le fichier d’en-tête suffit pour cela.

Quelques exemples:

  • extension de la classe std::exception pour créer une exception personnalisée
  • extension de la bibliothèque de stream pour créer des stream personnalisés dans votre application

Mais vous devez savoir que ne pas étendre les classes qui n’ont pas virtual destructor . Les exemples sont std::vector , std::ssortingng

Edit: Je viens de trouver une autre question SO sur ce sujet Extension de la bibliothèque standard C ++ par inheritance?

Il suffit d’avoir un fichier d’en-tête pour hériter de cette classe.
Les programmes C ++ sont construits en deux étapes:

  • Compilation
    Le compilateur recherche la définition des types et vérifie l’exactitude de la langue dans votre programme. Ceci génère des fichiers objects.
  • Mise en relation
    Les fichiers d’object compilés sont liés pour former un exécutable.

Donc, tant que vous avez le fichier d’en-tête ( nécessaire à la compilation ) et la bibliothèque ( nécessaire à la liaison ), vous pouvez dériver d’une classe.
Mais notons qu’il faut faire attention si cette classe est vraiment destinée à l’inheritance.
Par exemple: Si vous avez une classe avec destructeur non virtual cette classe n’est pas destinée à l’inheritance. Tout comme toutes les classes de conteneur de bibliothèque standard.

En bref, avoir une interface de classe suffit pour la dérivation, mais la sémantique de mise en œuvre et de conception de la classe joue un rôle important.