Comme d'hab : la première question à se poser : "quel est le public ?"
Cela a beaucoup de conséquences sur l'ordre. Un public newb' (comme celui du sdzoc) n'est pas prêt à entendre parler de la déduction de types ou de std::function dès les premiers chapitres. Ce genre d'info est à retarder.
Au sujet des pointeurs: il est normal de les voir au moment de la sémantique de valeur. Chez cette dernière, il faut montrer les aspects de duplication et à ce moment là, il est important de montrer les cas de ressources brutes.
+1 aussi à la factorisation des efforts. Voir avec Guillaume s'il n'y a pas moyen de collaborer avec lui.
Pour les tutos sur l'OO: Je suis méfiant vis à vis des tutos sur le sujet. La POO est souvent totalement incomprise et mal expliquée au fil des générations d'enseignants. On a vite fait de reproduire le trio infernal encapsulation, héritage et polymorphisme, là où je préfère allègrement: Abstraction (et donc l'orientation services et non données), Encapsulation (dont l'objectif est la préservation des invariants et non de cacher les attributs) (la corrolaire de ces deux est les setters, c'est pas OO), puis import de code (par héritage dans les langages mainstreams, et privé en particulier en C++), puis sous-typage et substituabilité (ce qui nous amène de nouveau au polymorphisme, et à l'héritage (qui est le moyen technique d'y parvenir dans les langages OO)). Oui, ce sont les mêmes choses mais avec des mots volontairement différents pour expliquer ces concepts. Et je n'hésite pas un seul instant à dire "l'héritage qui permet de réutiliser du code" est un argument marketing foireux : on sait réutiliser depuis gosub
et autres sous-routines. Par contre, en OO on peut importer du code. Certains langages supportent ça avec des mots clés dédiés (-> ruby), et beaucoup passent par l'héritage qui est aussi le seul moyen technique chez eux de procéder au sous-typage
Dans les présentations classiques, on a donc ce fichu trio infernal et des classes qui sont des agrégats de données qui se prêtent très mal à démontrer la substituabilité. Je préfère partir d'une procédure commune où j'ai des points de variations dynamiques, que je ne veux pas réaliser avec des switch/if, i.e. que je veux réaliser en respectant l'OCP. Cf l'exemple que je donne régulièrement du dépoussiérage de sol avec balai/aspi/aspi centralisé/aspi autoporteur de chats/…
Autre piège classique des présentations de l'OO: protected est mis en avant, alors qu'il présente des risques décapsulatoires bien supérieurs aux amis (qui tendent au contraire à renforcer l'encapsulation). Tout le monde n'a pas le même recul sur le sujet et ne présenta pas les mêmes choses.
Autre piège des cours OO: l'introduction itérativo-incrémentale des concepts OO. Ainsi, on part de la structure POD et on lui rajoute une fonction init()
au lieu de partir directement vers le constructeur qui assure que les invariants positionnés à l'initialisation seront positionnés à coups sûrs – init()
et autres setters, on peut oublier de les appeler. Je râle après cette approche, car je continue à voir beaucoup de codes qui la suivent.
Pour toutes ces raisons, je tends à préférer garder la maitrise des notions OO en C++, ou plus exactement dans les cours et tutos que je croise, pour être auteur, relecteur, ou gars qui fait de la pub.
+1 aussi à STL avant POO. Je me Lance de Francis Glassborrow suit cette approche et ça marche très bien. Pire, il n'explique pas comment écrire des classes, ce qu'est un pointeur, les templates, les exceptions, … Après, pour la SL, dans un premier temps il n'y a besoin que du vecteur, de string, et éventuellement des tables associatives. Et bien évidemment itérateurs et algos. Pour le reste, on peut botter en touche et dire où trouver la doc. Quand j'avais débauché David pour écrire les slides de cours de C++ au taf', pour les slides sur la SL, on faisait une présentation assez détaillée du vecteur pour enseigner à décoder la doc en ligne. La difficulté réside dans les choix des exemples et des exercices où il faut éviter les classes utilisateurs.
Pour les erreurs, il faut expliquer assez tôt qu'il existe un mécanisme qui permet de dérouter le flot d'exécution. L'exemple type : puch_back
qui n'a plus assez de mémoire. Quitte à rentrer dans les détails bien plus tard. Cela permettra de justifier les choix dans l'écriture de code exception-safe pour les opérateurs d'affectation p.ex. Pour les erreurs de programmation (et donc la PpC), je ne saurais pas où la placer. Dans mes cours au taf' (pour un public d'informaticiens professionnels), c'est le dernier gros sujet, mais je parle déjà bien plus tôt de la notion d'invariant (en continuité de l'encapsulation), et même des pré- et post-conditions pour le LSP.
PS: officiellement (i.e. dans tous les bouquins signés de Stroustrup), une méthode est une fonction membre virtuelle. Dit autrement, c'est un terme impropre au C++ où il faut préférer fonction membre.