Sì. I primi compilatori C ++ traducevano il codice in C prima di compilarlo con un normale compilatore C. Oggi, è così che funziona Vala. Vala si basa sul sistema oggetto GLib , che fornisce funzionalità orientate agli oggetti per C, ma è apparentemente piuttosto ingombrante. Vala semplifica il processo.
Come per un esempio, quanto segue sarebbe vagamente equivalente:
Java:
Person.java:
public class Person {
private String name;
private int age;
public Person(String name, int age) { /* code */ }
int getAge () {
return age;
}
String getName () {
return name;
}
void setAge (int age) {
this.age = age;
}
void setName (String name) {
this.name = name;
}
}
C:
Person.h:
/*
This line serves two purposes:
a. Declare the struct without revealing its attributes; this is
called an "opaque struct."
b. Let us use just 'Person' instead of 'struct Person' to refer to
the struct.
*/
typedef struct Person Person;
/* Constructor */
Person* person_new (const char *name, int age);
/* Destructor -- just a wrapper around free() for simple cases */
void person_free (Person *obj);
/* Other methods */
int person_get_age (const Person *obj);
const char* person_get_name (const Person *obj);
void person_set_age (Person *obj, int age);
void person_set_name (Person *obj, const char *name);
person.c:
#include <stdlib.h>
#include "person.h"
/* Now we define the struct. */
struct Person
{
int age;
char *name;
};
Person* person_new (const char *name, int age)
{
Person *obj = (Person*) malloc (sizeof(Person));
obj->name = name;
obj->age = age;
return obj;
}
void person_free (Person *obj)
{
free (obj);
}
int person_get_age (const Person *obj)
{
return obj->age;
}
const char* person_get_name (const Person *obj)
{
return obj->name;
}
void person_set_age (Person *obj, int age)
{
obj->age = age;
}
void person_set_name (Person *obj, const char *name)
{
obj->name = name;
}
Quindi per utilizzarlo dovresti fare qualcosa di simile al seguente:
Person *me = person_new ("James Jensen", 27);
printf ("Hi, I'm %s and I'm %i years old.\n",
person_get_name (me),
person_get_age (me));
person_free (me);
Puoi anche fare ereditarietà, ma è un po 'più complicato e non sono molto fiducioso nelle mie capacità di farlo. Tuttavia, l'approccio di base è qualcosa di simile al seguente (le correzioni sono benvenute):
importantperson.c:
#include <stdlib.h>
#include "person.h"
/* Please just imagine I wrote this. */
#include "importantperson.h"
struct ImportantPerson
{
Person super; /* Note that this is NOT a pointer. */
int importance;
};
ImportantPerson* importantperson_new (const char *name, int age,
int importance)
{
ImportantPerson *obj = (ImportantPerson*) malloc (sizeof(ImportantPerson));
person_set_name(&(obj->super), name);
person_set_age(&(obj->super), age);
obj->importance = importance;
return obj;
}
void importantperson_free (ImportantPerson *obj)
{
free (obj);
}
int importantperson_get_age (ImportantPerson *obj)
{
return person_get_age (&(obj->super));
}
/* ...other getters... */
void importantperson_set_age (ImportantPerson *obj, int age)
{
person_set_age (&(obj->super), age);
}
/* ...other setters... */
Se non mi sbaglio, a causa del modo in cui C organizza i dati, avere un oggetto non puntatore Person
come primo attributo di ImportantPerson
ti consente anche di fare ciò:
ImportantPerson *me = importantperson_new ("James Jensen", 27, 9001);
/* Now I humble myself a bit... */
Person *p = (Person*) me;
printf ("Hi, my name is %s and I'm %i years old.\n",
person_get_name (p),
person_get_age (p));
/*
Now, destructors can be a bit of a problem. If they weren't both just
wrapping free(), this would do the wrong thing:
person_free (p);
*/
importantperson_free (me);
Spero che chiarisca le cose. Come sempre, accolgo con favore correzioni da parte di programmatori esperti.