diff --git a/slides/opaque.md b/slides/opaque.md new file mode 100644 index 0000000000000000000000000000000000000000..d6f4f8d7970b86b97ca3595e8dabcc25f41e793a --- /dev/null +++ b/slides/opaque.md @@ -0,0 +1,99 @@ +--- +title: "Types opaques" +date: "2022-01-18" +patat: + wrap: true + margins: + left: 10 + right: 10 +--- + +# Types composés + +* Jusqu'ici les struct sont dans les `.h` et sont *transparents* + +```C +// table.h +typedef struct _table { + int *data; + int length; +} table; +// main.c +table tab; // membres de tab accessibles directement +tab.length = 10; +tab.data = malloc(tab.length * sizeof(int)); +tab.data[9] = 10; +``` + +# Types opaques + +* Afin de cacher les détails de l'implémentation. +* Afin d'éviter les modifications directs des données. +* Afin de protéger le monde de la dévastation! +* Définition de types **opaques**: + * Variables dans les structures ne sont pas accessibles. + * Variables dans les structures ne sont pas modifiables. + * Les variables ne sont même pas connues. +* Nécessité de passer par des fonctions pour initialiser/modifier les instances + de types opaques. +* Très souvent utilisés pour les structures de données abstraites (table de + hachage, pile, file, ...). + +# Utilisation d'un type opaque: problème? + +* Dans `opaque.h` + + ```C + struct table; + ``` +* Dans `opaque.c` + + ```C + struct table { + int a; + } + ``` +* Dans `main.c` + + ```C + int main() { + struct table t; + } + // error: storage size of ‘t’ isn’t known + ``` +* La taille de `table` n'est pas connue à la compilation! +* Comment faire? + +# Utilisation d'un type opaque: pointeur! + +* Dans `opaque.h` + + ```C + struct table; + struct table *create(); + void init(struct table **t); + ``` +* Dans `opaque.c` + + ```C + struct table { + int a; + } + struct table *create() { + struct table *t = malloc(sizeof(*t)); + } + void init(struct table **t) { + *t = malloc(sizeof(**t)); + } + ``` +* Dans `main.c` + + ```C + int main() { + struct table *t = create(); + init(&t); + t->a = 2; // Interdit, set(2) + printf("%d\n", t->a); // Interdit, get() + } + ``` +