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
Loading
---
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