From 2f83d2104d3895fe017c4885db1bebbd4311f562 Mon Sep 17 00:00:00 2001
From: Orestis Malaspinas <orestis.malaspinas@hesge.ch>
Date: Tue, 6 Nov 2018 14:54:20 +0100
Subject: [PATCH] ajout smart pointers

---
 index.md          |   1 +
 smart_pointers.md | 114 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 115 insertions(+)
 create mode 100644 smart_pointers.md

diff --git a/index.md b/index.md
index c77137e..391cc33 100644
--- a/index.md
+++ b/index.md
@@ -20,6 +20,7 @@ sansfont: Sans Serif
 - [4.1 Commentaires](commentaires.html).
 - [4.2 Gestion d'erreurs](errors.html).
 - [6.1 Méthodes](methods.html).
+- [6.2 Pointeurs intelligents](smart_pointers.html).
 - [6.2 Collections: String, Vector, HashMap](collections.html).
 - [7.1 Tests](tests.html).
 - [8.1 Itérateurs](iterators.html).
diff --git a/smart_pointers.md b/smart_pointers.md
new file mode 100644
index 0000000..b30e723
--- /dev/null
+++ b/smart_pointers.md
@@ -0,0 +1,114 @@
+---
+title: Cours de programmation séquentielle
+subtitle: Pointeurs intelligents
+author: Orestis Malaspinas
+sansfont: Sans Serif
+---
+
+# Pointeurs
+
+## Généralités
+
+- Un **pointeur** est une variable qui contient une adresse mémoire.
+- Cette adresse **pointe** vers des données.
+
+![Illustration: tableau.](figs/mem_ref_vec.svg){width=50%}
+
+- Question: Quel type de pointeur avons-nous déjà rencontré?
+	- Réponse: La référence.
+
+## Smart pointers
+
+- Un **pointeur intelligent** est un type abstrait qui rajoute des fonctionnalités au poiteur standard.
+	- Management automatique de la mémoire.
+	- Vérification de limites.
+- En particulier, ils permettent la désallocation de la mémoire de manière automatique:
+	- On peut avoir plusieurs pointeurs sur un espace mémoire.
+	- Quand le dernier pointeurs est détruit, l'espace mémoire est désalloué.
+	- Permet d'empêcher les fuites mémoires.
+- Il existe différents types: 
+	- Un poiteur unique est le propriétaire de ses données (quand il est détruit les données aussi).
+	- On compte le nombre de références sur des données, quand ce nombre tombe à zéro on détruit tout.
+
+## En Rust
+
+- Exemples: 
+	- `Vec<T>`{.rust}, `String`{.rust}: ces types possèdent de la mémoire et la manipule eux-mêmes.
+- Les pointeurs intelligent doivent implémenter deux traits:
+	- `Deref`{.ruist}: comment on déréférence le pointeur.
+	- `Drop`{.rust}: comment on détruit le pointeur.
+- Les trois cas les plus typiques (il y en a d'autres):
+	- `Box<T>`{.rust} pointeur unique qui alloue des données sur la pile.
+	- `Rc<T>`{.rust} "reference counted" type, qui permet de partager la propriété.
+	- `Ref<T>`{.rust} et `RefMut<T>`{.rust} qui permet d'imposer les règles de propriété à l'exécution plutôt qu'à la compilation.
+
+# Le type `Box<T>`{.rust}
+
+## Généralités
+
+- Utile pour stocker des données sur le tas.
+- La seule chose stockée sur la pile est le pointeur sur les données du tas.
+- Cas typiques d'utilisation:
+	- Quand la taille d'un type est inconnu à la compilation.
+	- Quand on veut transférer la propriété de grandes quantité de données mais s'assurer que les données ne seront pas copiées (juste le pointeur).
+
+## Utilisation
+
+<pre><code data-trim="hljs rust" class="lang-rust">
+fn main() 
+{
+    let num = Box::new(10);
+    println!("num = {}", num);  // déréférenciation automatique
+    println!("num = {}", *num); // déréférenciation explicite
+
+    let x = 10;
+    // seule la déréférenciation explicite marche
+    println!("Is {} equal to {}?. Answer: {}", num, x, *num == x); 
+
+    let y = &x;
+    // La seule différence est qu'ici nous avons une référence 
+    println!("Is {} equal to {}?. Answer: {}", y, x, *y == x);
+} 
+</code></pre>
+
+- Dans l'appel de fonctions/méthodes la déréférenciation se fait automatiquement.
+- Sinon elle doit être explicite.
+
+## Car pratique: la liste chaînée
+
+- Rust doit connaître la taille d'un type **à la compilation**.
+- Ici nous avons à faire à un type **récursif**: sa taille est potentiellement infinie.
+
+<pre><code data-trim="hljs rust" class="lang-rust">
+enum List {
+	Elem(i32, List),
+	Nil,
+}
+
+use List::{Elem, Nil};
+
+fn main() 
+{
+    let list = Elem(1, Elem(2, Elem(3, Nil)));
+} 
+</code></pre>
+
+## Car pratique: la liste chaînée
+
+- Avec un `Box<T>`{.rust} sa taille est connue.
+
+<pre><code data-trim="hljs rust" class="lang-rust">
+#[derive(Debug)]
+enum List {
+	Elem(i32, Box&lt;List&gt;),
+	Nil,
+}
+
+use List::{Elem, Nil};
+
+fn main() 
+{
+    let list = Elem(1, Box::new(Elem(2, Box::new(Elem(3, Box::new(Nil))))));
+    println!("{:?}", list);
+} 
+</code></pre>
-- 
GitLab