C'est relativement simple. Object1 est le premier élément de Object2, et ObjectAbstract le premier élément de Object1. Ce qui veut dire qu'en mémoire, si tu prends un pointeur vers un Object1 ou un Object2, il pointera vers les données de l'ObjectAbstract.
En ce qui concerne les classes, elles n'existent bien sûr pas en C, mais on peut facilement contourner le problème. En fait ce qui suit n'est que la manière donc le code C++ est interprété par le compilateur.
Disons que tu as une classe A (de mercedes):
class A
{
public:
A();
~A();
Run (int n);
private:
int i;
};
Comment le compilo peut-il traduire cela en C? Tout d'abord on regroupe les données de la classe en une struct (dont le données privées ne sont bien sûr pas accessible, mais ça en C c'est dur à controller):
struct A_struct
{
int i;
}
Et ensuite on écrit l'interface de la classe avec des fonctions C, dont le premier paramètre sera TOUJOURS un pointeur vers la structure dont elles sont l'interface:
/* constructeur et destructeur */
void A_init (struct A_struct * a);
void A_cleanup (struct A_struct * a);
/* Méthodes */
void A_Run (struct A_struct * a, int n);
Evidemment tu dois toi même appeler le constructeur et destructeur manuellement, et toujours passer ta structure aux méthodes de l'interface. Mais j'insiste sur le fait que c'est ainsi que cela se passe en interne. Si tu lances gdb sur un programme C++, tu verras que ça se passe en fait comme cela.
Ensuite, l'héritage... Soit la classe B:
class B : public A
{
....
};
En C on traduira comme Kilobug l'a dit par:
struct B
{
struct A struct_a;
}
Et comme les données en mémoire au début du pointeur de B sont les données de A (car elle a été déclarée au début de B), tu peux appeler A_Run comme ceci:
struct B monB;
A_Run ((A*)&monB, 2);
En faisant un simple forcage de type. Pour l'héritage multiple, comme je l'ai dit plus haut tu peux t'en sortir avec un peu d'arithmétique de pointeurs. C'est bien sûr moins pratique qu'un compilo C++ qui fera le boulot à ta place, mais ca peut être grandement utile et c'est bon à savoir.
[^] # Re: POO ?
Posté par Gnurou (site web personnel) . En réponse à la dépêche Debian GNU/Hurd G1. Évalué à 5.
En ce qui concerne les classes, elles n'existent bien sûr pas en C, mais on peut facilement contourner le problème. En fait ce qui suit n'est que la manière donc le code C++ est interprété par le compilateur.
Disons que tu as une classe A (de mercedes):
class A
{
public:
A();
~A();
Run (int n);
private:
int i;
};
Comment le compilo peut-il traduire cela en C? Tout d'abord on regroupe les données de la classe en une struct (dont le données privées ne sont bien sûr pas accessible, mais ça en C c'est dur à controller):
struct A_struct
{
int i;
}
Et ensuite on écrit l'interface de la classe avec des fonctions C, dont le premier paramètre sera TOUJOURS un pointeur vers la structure dont elles sont l'interface:
/* constructeur et destructeur */
void A_init (struct A_struct * a);
void A_cleanup (struct A_struct * a);
/* Méthodes */
void A_Run (struct A_struct * a, int n);
Evidemment tu dois toi même appeler le constructeur et destructeur manuellement, et toujours passer ta structure aux méthodes de l'interface. Mais j'insiste sur le fait que c'est ainsi que cela se passe en interne. Si tu lances gdb sur un programme C++, tu verras que ça se passe en fait comme cela.
Ensuite, l'héritage... Soit la classe B:
class B : public A
{
....
};
En C on traduira comme Kilobug l'a dit par:
struct B
{
struct A struct_a;
}
Et comme les données en mémoire au début du pointeur de B sont les données de A (car elle a été déclarée au début de B), tu peux appeler A_Run comme ceci:
struct B monB;
A_Run ((A*)&monB, 2);
En faisant un simple forcage de type. Pour l'héritage multiple, comme je l'ai dit plus haut tu peux t'en sortir avec un peu d'arithmétique de pointeurs. C'est bien sûr moins pratique qu'un compilo C++ qui fera le boulot à ta place, mais ca peut être grandement utile et c'est bon à savoir.
Voila, j'espère avoir été clair :)