Skip to content
Snippets Groups Projects
Verified Commit 98f71d62 authored by orestis.malaspin's avatar orestis.malaspin
Browse files

added opaque

parent 4fbf3dd8
No related branches found
No related tags found
No related merge requests found
---
title: "Types opaques"
date: "2023-02-26"
---
# 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!
\footnotesize
* 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));
return 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()
}
```
# Un peu plus joli: typedef! (1/2)
* Dans `opaque.h`
```C
struct _table;
typedef struct _table * table;
void init(table *t);
void set_a(table t, int a);
int get_a(table t);
```
* Dans `opaque.c`
```C
struct _table {
int a;
}
void init(table *t) {
*t = malloc(sizeof(**t));
(*t)->a = 0;
}
void set_a(table t, int a) {
t->a = a;
}
int get_a(table t) {
return t->a;
}
```
# Un peu plus joli: typedef! (2/2)
* Dans `main.c`
```C
int main() {
table t;
init(&t);
set_a(t, 10);
printf("%d\n", get_a(t));
}
```
* On a fait les fonctions `get_a()` et `set_a()` comme exemples, mais...
. . .
* c'est pas forcément nécessaire d'implémenter (`get/set`).
. . .
* Par exemple, pour la hashmap on `get/set` les variables des structs!
## Yaka
* Utiliser les types opaques pour la hashmap!
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment