objet de classe cast en objet struct C / C ++
J'ai deux projets l'un en C et l'autre en C ++ et j'essaie de convertir un objet de classe en C ++ en un objet de structure en C.Par exemple, j'ai un objet de myClass que j'essaye de convertir en myStru comme suit:
Dans mon projet C ++, j'ai cette classe:
class myClass{
myClass();
~myClass();
char *data;
int var;
}
Dans mon projet C, j'ai cette structure:
struct myStru {
char *data;
int var;
};
typedef struct myStru myStru;
Maintenant, dans mon projet C ++, je crée un objet à partir de myClass
:
myClass *classObj = new myClass();
classObj->data = new char[10];
classObj->var = 99;
Dans mon projet C, je reçois en classObj
tant que pointeur vide et j'essaye de le caster comme suit:
myStru *struObj = (myStru*)malloc(sizeof(struct myStru));
struObj = (myStru*) classObj;
printf(" struObj->var %d \n", struObj->var); // this print 99
Je le fais plus tard dans mon projet C ++
delete []classObj->data; // I know smart pointers can be used here but this is not my point in this question now
delete classObj;
Est-ce que ce que je fais ici est correct? c'est-à-dire, en jetant classObj
de struObj
cette façon?
L'exemple complet peut être trouvé ici (merci @Borgleader) http://coliru.stacked-crooked.com/a/05543b944ee23f2f
EDIT: J'ai trouvé une bonne réponse à ma question dans cet article (voir Accéder aux classes C ++ à partir de C): https://www.oracle.com/technical-resources/articles/it-infrastructure/mixing-c-and-cplusplus.html
Réponses
Je ne suis pas sûr à 100%, car c'est du C ++ et vous ne pouvez jamais l'être, mais je pense que ce n'est pas un comportement défini.
Vous ne pouvez pas accéder aux membres d'une structure via un pointeur vers un membre vers une autre structure. Une exception notable à cette règle consiste à accéder à la séquence initiale commune de deux structures membres d'une union.
Cela pourrait fonctionner si vous héritiez en fait de votre classe de la structure à la place.
Alternativement, l'autre exception est que vous pouvez en toute sécurité memcpy
entre ces structures, AFAIR.
Cette question concerne l'interopérabilité et vous n'obtiendrez jamais de réponse définitive car elle repose sur des aspects définis par l'implémentation du compilateur C et C ++. Les struct
et les class
sont des types compatibles avec la mise en page en termes C ++. Il est très clair que déclarer un a class
et un a struct
n'est pas un problème et parce qu'ils ont tous les deux le même accès aux membres pour tous leurs membres (bien que différents les uns des autres) sont compatibles (au moins en C ++ 14, je crois) .
Le mieux que la norme va offrir est:
Remarque: les classes de mise en page standard sont utiles pour communiquer avec du code écrit dans d'autres langages de programmation. Leur disposition est spécifiée en 12.2. - note de fin
L' intention est que ces classes (qui sont à la fois compatibles avec la disposition standard et la disposition) soient interopérables. Si vous utilisez le même compilateur dans deux modes, il serait «décevant» si cela ne fonctionnait pas. Mais c'est le mieux que vous soyez «décevant» - consultez la documentation.
Je m'interroge un peu sur la gestion des ressources dans la stratégie globale. Vous avez déclaré un destructeur dans le C ++ class
et c'est bien ce n'est pas le cas virtual
!), Mais vous le copiez dans un struct
côté C, si le code C a une fonction `` destructor like '' pour détruire ses objets, ce qui peut entraîner des J'ai cloné l'objet C ++ au niveau du bit (espérons-le!).
Si C appelait free(s->data)
sa copie d'un objet construit en C ++ qui avait utilisé, new
vous provoquiez un comportement indéfini. Cela pourrait être le cas exceptionnel qui justifie l'utilisation malloc()
du côté C ++ pour la compatibilité.
Donc, c'est probablement OK, mais vous comptez sur les capacités d'interopérabilité entre C et C ++ et les deux normes vous mènent aussi loin que possible, mais par définition, vous utilisez des fonctionnalités définies par l'implémentation.
Par cette note, nous savons que la norme est prête à fonctionner et elle le fera probablement. Bonne chance!