C pour un programmeur orienté object

Ayant appris Java et C ++, j’ai appris la méthode OO. Je veux me lancer dans un projet assez ambitieux, mais je veux le faire en C. Je sais comment décomposer les problèmes en classes et comment les transformer en hiérarchies de classes. Je sais résumer la fonctionnalité en classes et interfaces abstraites. Je suis même quelque peu compétent pour utiliser le polymorphism de manière efficace.

Le problème est que lorsque je suis confronté à un problème, je sais comment le faire d’une manière orientée object. Je suis devenu trop dépendant des philosophies et méthodologies de conception orientées object.

Je veux apprendre à penser de manière ssortingctement procédurale. Comment faire des choses dans un monde sans classes, interfaces, polymorphism, surcharge de fonctions, constructeurs, etc.

Comment représentez-vous des concepts complexes en utilisant uniquement des struct non orientées object? Comment pouvez-vous remédier à un manque de surcharge de fonctions? Quels sont quelques trucs et astuces pour penser de manière procédurale?

La procédure consiste à avoir, d’un côté, vos structures de données et, de l’autre, vos algorithmes. Ensuite, vous prenez vos structures de données et les transmettez à vos algorithmes. Sans encapsulation, cela demande un peu plus de discipline et si vous augmentez le niveau d’abstraction pour faciliter la tâche, vous réalisez une partie considérable de OO en C.

Je pense que vous avez un bon plan. Faire les choses de la manière complètement OO en C, bien que tout à fait possible, est assez pénible pour que vous le laissiez vite tomber de toute façon. (Ne combattez pas la langue.)

Si vous voulez une déclaration philosophique sur la correspondance du mode OO avec le mode C, cela se fait en partie en poussant la création d’object vers le haut. Un module peut toujours implémenter son object comme une boîte noire, et vous pouvez toujours utiliser un style de programmation raisonnable, mais fondamentalement, il est trop pénible de cacher l’object, de sorte que l’appelant l’atsortingbue et le transmet, plutôt que le module et en le retournant. Généralement, vous jouez avec des getters et des setters, ou les implémentez sous forme de macros.

Pensez également que toutes les abstractions que vous avez mentionnées constituent une couche relativement mince au-dessus de structs ordinaires, de sorte que vous n’êtes pas vraiment très loin de ce que vous voulez faire. Ce n’est tout simplement pas emballé aussi bien.

Le toolkit C comprend des fonctions, des pointeurs de fonction et des macros. Les pointeurs de fonction peuvent être utilisés pour émuler le polymorphism.

Vous prenez le chemin inverse que les anciens programmeurs C ont fait pour apprendre OO.

Même avant que c ++ soit un standard OO, les techniques étaient utilisées en C.

Ils ont inclus la définition de structures avec un pointeur sur srtuct (généralement appelé ceci …), puis la définition de fonctions de pointeur dans la structure et, lors de l’exécution, initialiser ces pointeurs vers les fonctions correspondantes. Toutes les fonctions reçues en premier paremeter le pointeur struct this.

Ne pensez pas C de manière totalement POO. Si vous devez utiliser C, vous devriez apprendre la programmation procédurale. Faire cela ne prendrait pas plus de temps que d’apprendre à réaliser toutes les fonctionnalités de POO en C. En outre, l’encapsulation de base est probablement satisfaisante, mais de nombreuses autres fonctionnalités de POO viennent avec une surcharge de performances lorsque vous les imitez (pas lorsque le langage soutenir la POO). Les frais généraux peuvent être énormes si vous suivez scrupuleusement la méthodologie de conception C ++ pour représenter chaque petite chose sous forme d’object. Les langages de programmation ont des objectives spécifiques dans la conception. Lorsque vous dépassez la limite, vous devez toujours payer quelque chose comme coût.

La méthode standard pour effectuer un comportement polymorphe dans C consiste à utiliser des pointeurs de fonction. Vous trouverez de nombreuses API C (telles que les standards qsort(3) et bsearch(3) ) bsearch(3) pointeurs de fonction en tant que parameters; certains non standards, tels que qsort_r prennent un pointeur de fonction et un pointeur de contexte ( thunk dans ce cas) qui ne servent à rien d’autre que d’être renvoyés à la fonction de rappel. Le pointeur de contexte fonctionne exactement comme le pointeur this dans les langages à object, lorsqu’il traite avec des objects de fonction (par exemple, des foncteurs).

Voir également:

  • Pouvez-vous écrire du code orienté object en C?
  • Orientation d’object en C

Ne pensez pas que vous devez mettre de côté vos connaissances du travail orienté object – vous pouvez “programmer dans le langage” .

J’ai dû travailler en C après avoir été principalement expérimenté dans le travail orienté object. C permet à un certain niveau de concepts d’object de passer à travers. Au travail, je devais implémenter un arbre rouge-noir en C, à utiliser dans un algorithme de balayage pour trouver les points d’intersection dans un ensemble de segments. Comme l’algorithme utilisait différentes fonctions de comparaison, j’ai finalement utilisé des pointeurs de fonction pour obtenir le même effet que lambdas dans Scheme ou des delegates en C #. Cela a bien fonctionné et a également permis à l’arbre équilibré d’être réutilisé.

L’autre caractéristique de l’arborescence équilibrée consistait à utiliser des pointeurs vides pour stocker des données arbitraires. Encore une fois, les indicateurs de vide et de fonction en C sont un problème (si vous ne connaissez pas leurs tenants et aboutissants), mais ils peuvent être utilisés pour créer une structure de données générique.

Une note finale: utilisez le bon outil pour le travail. Si vous souhaitez utiliser le langage C simplement pour maîsortingser une technique procédurale, choisissez un problème bien adapté à une approche procédurale. Je n’avais pas le choix en la matière (application héritée écrite en C, et les gens exigent le monde et refusent d’entrer dans le 21ème siècle), alors je devais être créatif. C est idéal pour les abstractions faibles / moyennes de la machine, par exemple si vous souhaitez écrire un programme d’inspection de paquets en ligne de commande.