Big-tuto C++

a marqué ce sujet comme résolu.

Quel est la différence concrète entre un type natif et une classe si on enlève le fait que les opérations sur l'un sont natives au processeur ?

Ksass`Peuk

Je dirais la paire constructeurs/destructeurs, qui permettent de manipuler des ressources avec la RAII. Après c'est vrai qu'avec les conteneurs modernes de la STL on peut se passer de la gestion des allocations (sauf si on écrit son propre allocateur) et on ne voit pas trop la différence, à part que les types natifs sont de simples nombres (si l'on ne parle pas de tableaux et de pointeurs), qu'on manipule donc avec des opérateurs, ou des fonctions externes comme celles de std::math.

Mais il y a d'autres ressources que la mémoire (fichier, lock d'un mutex, etc).

Je dirais la paire constructeurs/destructeurs, qui permettent de manipuler des ressources avec la RAII.

Tolf

C'est encore un point qui rend la différenciation entre les types natifs et les classes plus difficile : leur comportement observable en terme de gestion de ressources est le même : fin de portée = fin de l'accès à ma ressource que ce soit un bête entier, ou un fichier, ou la commande de mise à feu de mon canon-orbital.

C'est même précisément l'intérêt du RAII donner à tous nos éléments le même comportement en terme de gestion de ressource en se basant sur la mécanique de la pile. Une ressource inaccessible depuis tout point de programme et une ressource qui doit ne plus exister.

Mais on est déjà trop proche de l'implémentation. La question est purement logique. Dans ce code :

1
2
3
4
5
6
7
8
9
int main ( int argc, char** argv )
{
    Int32 a{ 42 };
    Int32 b{ 42 };

    std::cout<< a + b <<std::endl;

    return 0;
}

Les éléments a et b sont ils des variables natives ? des objets ? des struct ? Réponse : ça peut être les trois :

1
using Int32 = int;
1
2
3
4
5
6
7
struct Int32{
  int i;

  operator int&(){
    return i;
  }
};
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
class Int32{
public:
  friend Int32 operator+(Int32 a, Int32 b);
  friend std::ostream& operator<<(std::ostream& os, Int32 i);

  Int32(int i = 0) : i{i}{}

private:
  int i;
};

Int32 operator+(Int32 a, Int32 b){
  return Int32{ a.i + b.i };
}
std::ostream& operator<<(std::ostream& os, Int32 i){
  return os<<i.i;
}

Différence dans le comportement observable : aucune. Différence au niveau du code généré : aucune.

Je suis tout à fait d'accord avec Ksass (je ne mets pas la fin du pseudo pour ne pas avoir un affichage bizarre), je ne vois pas pourquoi on aurait besoin que le lecteur connaisse la POO pour lui apprendre à utiliser la SL ; on lui dit que c'est un ensemble d'outils et de types offrant telle et telle fonctionnalité et s'utilisant avec telle syntaxe.

(D'ailleurs, j'avais déjà écrit une jolie réponse pour te l'expliquer la première fois que tu avais posé la question, mais j'ai fermé la page où je le rédigeai sans faire exprès et j'ai eu la flemme de le réécrire.)

EDIT : struct et class peuvent s'utiliser de la même façon mais n'ont pas la même sémantique, donc je ne suis pas d'accord avec toi, paolo10. ET si trois choses s'utilisent exactement de la même façon, je ne vois pas pourquoi on irait expliquer à un débutant qu'elles sont différentes. On lui expliquera, mais plus tard.

+0 -0

Je suis tout à fait d'accord avec Ksass (je ne mets pas la fin du pseudo pour ne pas avoir un affichage bizarre), je ne vois pas pourquoi on aurait besoin que le lecteur connaisse la POO pour lui apprendre à utiliser la SL ; on lui dit que c'est un ensemble d'outils et de types offrant telle et telle fonctionnalité et s'utilisant avec telle syntaxe.

mehdidou99

Tout à fait d'accord mais ça n'empêche pas de lui expliquer pourquoi.

Dans le premier int32 est un int dans les deux autres il contient un int. Une structure et une classe en c++ c'est la même.

paolo10

et même un désassembleur / inspecteur de mémoire ne pourra pas faire la différence (4 octets chacun). Non vraiment, il n'y a aucune différence du point de vue de l'utilisateur de ce type.

+1 -0

Oui, mais on leur explique après ! On commence par le plus facile avant d'aller au plus complexe ! En plus, tu te contredis, ton raisonnement n'a ni queue ni tête. Tu as dis que l'on ne pouvait pas leur expliquer la SL avant la POO, maintenant tu dis qu'on peut mais que "ça n'empêche pas de leur expliquer pourquoi"

+0 -0

Dans le premier int32 est un int dans les deux autres il contient un int.

paolo10

Est ce que ça induit une différence d'utilisation ? Non, aucune. Est ce que ça change la sémantique du programme principal ? Non plus. Est ce que ça change le code généré à la compilation ? Même pas. Et encore, l'exemple n'est pas fourbe.

Qu'on soit dans le cas d'une classe ou d'un type natif, on peut créer des éléments de ce type et on va avoir des opérations capables de manipuler ces éléments. Opérations que l'on peut définir ou re-définir si cela nous est nécessaire. Ce ne sont rien que des portions de mémoire sur lesquelles on peut agir.

Sur le format je rejoins @gbdivers. Avoir un big-tutos ici ne serait pas plus mal. Quand on y repense, c'est d'ailleurs ce système qui faisait le succès du sdz avec les tutos de Mateo21. Notamment aujourd'hui il existe trop peu de cours complet en français qui soit à jour avec la norme1

J'avais tenté de faire un projet en C++ pour me mettre à jour car je connaissais les nouvelles normes qu'en théorie (et encore) et je n'avais jamais vraiment eu l'occasion de m'y mettre.

Mon soucis a été principalement de rencontrer des ressources très théoriques sur le sujet. Je me souviens qu'en je cherchais de l'informations sur les pointeurs intelligents ou bien sur la sémantique de move. On te donne des exemples très minimalistes et ce fut difficile (pour moi) d'appliquer ce que j'avais vu sur mon projet.

De mon point de vue, il ne faudrait pas lésiner sur les exercices/projets. Les exercices peuvent être très simples comme

  • demander d'implémenter une fonction
  • deviner le type d'une fonction
  • compléter un code etc…

C'est ce qui manque à mon goût lorsque j'ai voulu apprendre certaines notions.

Maintenant, souvenez-vous aussi qu'un tel sujet avait été crée il y a un an pour le C, et même si il y a eu de supers idées, aucun tutoriel n'a commencé car trop ambitieux et on se chamaillait sur des détails. Donc si vous êtes motivé, il faut qu'il y en ait au moins un qui commence le tutoriel et bataillez-vous après, sinon vous ne commencerez jamais je pense.


  1. J'en connais qu'un d'ailleurs et c'est celui ci : http://guillaume.belz.free.fr/doku.php?id=programmez_avec_le_langage_c 

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.

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.

Ouep. C'est pour ça qu'il pourrait être intéressant de suivre la méthode de nohar : on partage le travail en plusieurs composantes si possible indépendantes. Comme ça, chacun s'adresse au public qu'il souhaite viser. Un big tuto implique d'être d'accord sur le contenu, l'ordre, la quantité de détails, etc.

+0 -0

Tout le monde et contre moi !

Je ne vais donc pas chercher à me battre plus la majorité a voté pour repousser le plus possible l'apprentissage de la POO.

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.

lmghs

Tout a fait d'accord ce serait à introduire avec la conversion de type.

Quant à toi Vayel tu es hors sujet tu a vu le titre du forum ?

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.

Ouep. C'est pour ça qu'il pourrait être intéressant de suivre la méthode de nohar : on partage le travail en plusieurs composantes si possible indépendantes. Comme ça, chacun s'adresse au public qu'il souhaite viser. Un big tuto implique d'être d'accord sur le contenu, l'ordre, la quantité de détails, etc.

Vayel

Ici, je trouve que l'on perd une certaine cohérence. Ensuite, j'ai un peu l'impression que cet argument n'est pas du tout dans l'idée présentée par Nohar pour Python.

Pour preuve, regardez l'image qu'il présentait :

Plan pour un ensemble de tutoriels python

On retrouve quand même une base générique qui est Python. Le reste, c'est juste que des cas d'applications où presque (on enlève la branche POO/concepts avancés).

L'idée de faire un big tuto C++ ne va pas à l'inverse de l'idée présentée par Nohar au contraire. C'est pas comme si le tuto dont on parle allait présenter les policy où le méta-template programming.

Cette méthode de découpage doit assurer une certaine cohérence, et donc il ne faut pas faire un découpage trop fin à mon avis.

Maintenant, souvenez-vous aussi qu'un tel sujet avait été crée il y a un an pour le C, et même si il y a eu de supers idées, aucun tutoriel n'a commencé car trop ambitieux et on se chamaillait sur des détails. Donc si vous êtes motivé, il faut qu'il y en ait au moins un qui commence le tutoriel et bataillez-vous après, sinon vous ne commencerez jamais je pense.

Saroupille

Il y a celui que Mewtow, Lucas, paraze, Taurre et moi avions écrit sur PDP qui est actuellement en bêta et GuilOooo est dessus pour la validation.

lmghs, je garde précieusement ton message sous le coude pour justement ne pas tomber dans ce piège.

Je suis totalement contre le fait de dire qu'un type natif et une classe c'est la même chose. Mais je suis d'accord pour introduire les classes avec std::string.

paolo10

Il est normal d'expliquer la différence entre des types prédéfinis, et les types utilisateurs (qu'ils soient standards ou non). Après, … il n'y a guère plus besoin de rentrer dans les détails au démarrage.

NB: dans la norme, je vois souvent object employé en place de variable. Il n'empêche que j'essaie de garder la différence et juste employer variable et type quand mes explications se veulent génériques.


Concernant le problème de public que je soulève, le tutos multi-documents ne va pas forcément fonctionner correctement. Exemple typique: Deuxième chapitre sur la POO, classes à sémantique de valeurs (dans le premier et dans le désordre: constructeurs, invariants, destructeurs (orientés log pour l'instant), membres, visibilités, syntaxe de définition de classe, compil séparée).

Si le public est pur débutant, on présente à ce moment là les notions de copie, et d'égalité. Et probablement les interactions avec des ressources, qu'elles soient brutes ou sous capsules RAII.

Mais si le public est plus qu'averti, il peut être intéressant d'avoir un cours organisé par thèmes. Et il faudra donc caser au milieu la sémantique de déplacement, et les interactions avec la copie (en termes de choix/résolution de surcharges). Sachant que pour le 3e cours sur les classes à sémantiques de valeurs, on peut aussi aborder le déplacement.

Ou alors, il faut intercaler ça dans le 4e où sont présentées les choses applicables aux deux sémantiques (héritage multiple, comment hériter correctement (héritage privé, visibilité protégé)).

Autre exemple: Le choix de parler de std::function et des lambdas au milieu des fonctions est un choix d'organisation thématique. Seulement, les std::functions, et surtout, les lambdas s'expliquent mieux après la présentation des foncteurs… Ce qui n'ira pas pour des débutants purs.

paolo10, arrêtes les enfantillages s'il te plait. Qu'il y ait des divergences de point de vue, c'est normal dans un projet de tutos avec plusieurs auteurs mais cela ne doit pas aller à l'encontre d'une discussion constructive. Tu ne fais pas avancer schmilblick en râlant de la sorte.

Et cette remarque :

Quant à toi Vayel tu es hors sujet tu a vu le titre du forum ?

N'a pas sa place ici (gérer les HS et autres, c'est mon boulot, pas le tien). Scinder un big-tuto C++ en plusieurs tutos modulables est effectivement une bonne idée.

+1 -0

Hey j'ai dit que j'étais d'accord ! Je me plis à la majorité. Tout les auteurs sont d'accord pour faire un big-tuto celui-ci étant déjà commencé ( Et oui ! On se parle par MP ).

Le forum reste cependant ouvert à vos questions et remarques.

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte