Pourtant sur ce forum y a des gens qui ont largement le niveau visiblement... Et t'as raison mais si tu savais depuis combien de temps je cherche...
Pourtant sur ce forum y a des gens qui ont largement le niveau visiblement... Et t'as raison mais si tu savais depuis combien de temps je cherche...
En vrai l'implémentation 'zend_object' de PHP m'a l'air parfaite (Excepté ceci: 'Using offsetof() here has one implication : the zend_object must be the last member of your_custom_struct object. Obviously if you declare types after it, you'll run into trouble accessing them, because of the way zend_object is allocated now in PHP 7.'), mais faudrait qu'on me l'explique vite fait, parce que c'est du code beaucoup trop avancé pour moi...
Si vraiment, vraiment, tu veux faire de l'OO en C, tu as COS (https://github.com/CObjectSystem/COS) -- que je ne pensais pas encore maintenu par Laurent Deniau.
Au moins, il offre des choses que le C++ n'a pas comme le multi-dispatch.
Bonjour,
il y a aussi tout simplement GObject → https://developer.gnome.org/gobject/stable/. Cette implémentation est fiable, testée, en production (utilisée par GLib, GDK, GTK, Gnome, …).
Merci de vos réponse, mais je vous renvoie à mon premier post: 'ou "utilise des choses existantes", mais je répondrais que je préfère le C aux autres langages, et que j'ai besoin de quelque chose de portable (donc on oublie GObject et tout le tralala)'... Ceci étant, si quelqu'un sait comment fonctionne la logique GObject...
GObject et tout le tralala est porté sur Windows et Mac entre autre ...
Ce n'est sans doute pas la panacée, c'est sans doute un peu compliqué mais c'est sans doute l'un des cas de «C orienté objet» les mieux fini et défini. D'ailleurs à un tel point que la «majorité» des utilisateurs ne le remarquent même pas .
Apparemment tu as déjà travaillé avec GObject. Tu as donc constaté qu'il y à beaucoup de dépendances et que c'est un vrai casse-tête dès qu'on sort de linux... En plus j'ai pas besoin d'un truc aussi complet et optimisé
Je cherche toujours des solutions...
En ce qui concerne l'appel opaque de fonctions , une solution que je propose est citée dans cette discussion à partir du post #13...
C'est ce qui est utilisé dans X11, et qui l'a été aussi dans Motif, et less..
TRES TRES efficace...
Et très OO..
On peut trouver les exemples complets (héritages de classe et fonctions) dans le code de XFree86 par exemple...
Bonjour,
Je n'ai pas lu ton message, et donc pas les réponses, mais la meilleure manière est d'utiliser un langage adapté d'origine !
C++ convient très bien, il y en a d'autres.
là c'est aller chercher midi à quatorze heures quelque part.
L'intérêt du C++ notamment c'est la modularité, de créer et instancier des entités indépendante des unes des autres.
Bref je vais me répéter mais dans un projet informatique plus il y a de la modularité mieux c'est avec des entités indépendantes des autres.
Sinon c'ela donne du code spaghetti et pour faire une modification elle doit être impactée dans tout le code.
Ensuite concrétement pour faire de l'orienté objet en C++ à part déclarer pléthore de pointeurs/variables globales je ne vois pas autrement.
Et les variables globales c'est une très mauvaise habitude de programmation faut éviter
le C plus stable que le C++ ? Elle est bien bonne celle-là
Apparemment tu n'as jamais fait de programme en C.
Si tu déclares un pointeur et qu'il n'est pas alloué avec malloc eh bien ça va planter.
En C++ aussi avec new() mais il y aura le runtime qui va contrôler.
Et puis il y a aussi les smart ponters en C++
dans ce cas-là comme il est expliqué ce n'est pas vraiment un pointeur "identitaire" car il est passé en paramètre..
l'intérêt du pointeur this c'est qu'il soit totalement indépendant d'entités externes.
Bref en C++ le pointeur this est véritablement local,substentielle et intrinsèque à la classe qu'il est supposé désigner.
Or dans l'exemple que tu donnes il doit être déclaré et alloué ailleurs.
c'est exact mais avec un compilateur C++ c'est le compilateur qui gère tout ça notamment les tables virtuelles
Avec un compilateur C il faut tout faire par soi-même
oui COM c'est une techno de Microsoft et c'est quelque part l'ancêtre de .NET.
C'est majoritairement des interfaces C++.
Une interface C++ c'est une classe abstraite qui équivaut à 0.
Elle peut être déclarative sans implémentation.
Le gros intérêt d'une interface c'est encore une fois la modularité.
Tu peux le faire aussi en C mais tu n'as pas 1) l'encapsulation pour protéger tes ressources 2) la destruction automatique
Une interface COM [mais pas que COM] c'est un ensemble de fonctionnalités.
C'est moi qui avait donné cet exemple pour l'interface de base IUnknown qui utilise le compteur de référencse et notamment la question de ghost2002 sur le problème de race conditions lors de la destruction.
Et apparemment j'avais tord
Trouvé sur MSDN : Implementing IUnknown in C
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 STDMETHODIMP_(ULONG) STATUS_Release(LPMYSTATUSOBJ lpMyObj) { LONG cRef; // Check the size of the vtable. if (!lpMyObj) { return 1; } // Check whether the vtable is correct. if (lpMyObj->lpVtbl != &vtblSTATUS) { return 1; } InterlockedIncrement(lpMyObj->cRef); cRef = --lpMyObj->cRef; InterlockedIncrement (lpMyObj->cRef); if (cRef == 0) { lpMyObj->lpVtbl->Release(lpMyObj); DeleteCriticalSection(&lpMyObj->cs); // Release the IMAPIProp pointer. lpMyObj->lpProp->Release(lpMyObj->lpProp); lpMyObj->lpVtbl = NULL; lpMyObj->lpFreeBuff(lpMyObj); return 0; } return cRef; }
En fait une grande partie du problème serait résolu si je pouvais passer en même temps qu'un pointer générique sont type, pour pouvoir le caster. Si je pouvais faire ça je saurais comment implementait mon héritage
Humouais, j'en suis pas encore aux smarts pointers...
Pour qu'un objet de base puisse appliquer ses méthodes à lui même mais aussi à l'objet qui hérite, il faut qu'il prenne un pointeur sur ce dernier. Comme on ne sait pas de quel type d'objet il s'agit, on doit utiliser un void*. Ça donne donc un truc comme ça:
Obj->base->vptr->print(Obj);
Au lieu de:
Obj->base->vptr->print(Obj->base);
C'est donc à l'objet de base de se "trouver lui-même" dans la zone mémoire pointer par le void*. Le problème c'est que sans connaître le type de paramètre (donc de l'objet qui hérite), afin de pouvoir le caster, je vois pas comment c'est possible... Et même, autant ça fonctionnerait pour deux objets (B hérite de A), mais qu'en est-il avec plus (C hérite de B qui hérite de A) ?
PS: "Dans une implémentation normale du C++, le RTTI se manifeste sous la forme d'un objet std::type_info stocké au début de la table virtuelle, juste avant la succession des adresses des fonctions virtuelles. On peut suivre la même stratégie en C.". Comment c'est possible ça en C ?
Est-ce que je fais fausse route ?
L'héritage en C, ce n'est vraiment pas la joie. COM contourne plus ou moins ça avec ses interfaces, l'agrégation et la composition (et le fait que dans les tutoriels Microsoft, une bonne classe COM, pour être compatible avec l'agrégation COM, utilisait des classes internes n'implémentant qu'une seule interface chacune plutôt qu'hériter de plusieurs d'un coup).
En C, si tu veux faire une structure genre type_info, ça peut être tout simplement le premier membre d'une structure servant de vtable. Ou une structure retournée par une "fonction virtuelle" comme Microsoft utilisait en C++ dans MFC, qui date d'avant que les normes C++ sur la RTTI soient fixées.
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager