La programmation en C++ moderne

Apprenez la programmation de zéro jusqu'à l'infini !

a marqué ce sujet comme résolu.

Tout à fait, on a déjà présenté les tests unitaires. Par contre, on a effectivement décidé (même si on ne s’interdit jamais de changer d’avis) que l’on ne présenterait finalement pas Boost.Test.

mehdidou99

Je pense que c’est une bonne idée car pour l’instant les assert suffisent pour de « petits » projets pour l’instant.

Quelques petites corrections mineures. Globalement la partie III est prête.

Dédicace à @nohar pour la suggestion de faire un cours incluant ces éléments qui tournent autours du langage lui-même.


Bonjour les agrumes !

La bêta a été mise à jour et décante sa pulpe à l’adresse suivante :

Merci d’avance pour vos commentaires.

Déjà trois mois, que le temps passe. Allez, on s’y remet, avec la partie la plus attendue si on en croit ceux qui cherche une alternative à OC, la POO ! Le premier chapitre est en cours. N’hésitez vraiment pas à nous faire des retours, on a vraiment envie de se donner à fond pour sortir une partie V en or. On a besoin de vous. ;)


Bonjour les agrumes !

La bêta a été mise à jour et décante sa pulpe à l’adresse suivante :

Merci d’avance pour vos commentaires.

Salut à tous,

Voilà le premier chapitre, presque complet. J’ai peut-être encore à peaufiner la partie sur les constructeurs, mais sinon ça a bien avancé. N’hésitez pas à faire vos remarques. Surtout toi, @lmghs. :)

Merci d’avance à tous.


Bonjour les agrumes !

La bêta a été mise à jour et décante sa pulpe à l’adresse suivante :

Merci d’avance pour vos commentaires.

Dans "Donc, en c++", les attributs d’une fonction c’est la même chose qu’un champs (field) ?

Ici

C’est pas litchy mais litchi (en tout cas si c’est le fruit). :ange:

Faudra parler de la mutabilité dans la partie sur la POO je pense parce que c’est tout de même important. :-°

Ici

Ça correspond à quoi quand ça met inf quand il y a la division par zéro ?

Ici juste avant le titre

Ici, j’ai effectuée

Effectué sans e puisque ça ne s’accorde pas avec l’auxiliaire avoir.

Quand vous parlez de la PPC ça me fait repenser au C++20 qui va arriver. :D

Voilà c’est tout pour moi. :magicien:

Merci pour tes retours. :)

Dans "Donc, en c++", les attributs d’une fonction c’est la même chose qu’un champs (field) ?

Vanadiae

Les attributs d’une classe, tu veux dire ?

C’est pas litchy mais litchi

Vanadiae

Eh bien non, c’est un chat. :D

Faudra parler de la mutabilité dans la partie sur la POO je pense parce que c’est tout de même important. :-°

Vanadiae

On y compte bien, dans le chapitre suivant, qui vient d’être ajouté. :)

Ça correspond à quoi quand ça met inf quand il y a la division par zéro ?

Vanadiae

À l’infini. Comme diviser par zéro est un comportement indéterminé, qui n’a aucun sens, tout peut apparaître comme résultat. Donc la valeur affichée n’est pas très importante.

Quand vous parlez de la PPC ça me fait repenser au C++20 qui va arriver.

Vanadiae

Et tu as tout à fait raison. D’ailleurs, le cours sera bien mis à jour pour suivre l’évolution de la norme.

Dire que quand ce projet d’écrire un cours C++ est né dans nos têtes, C++17 était attendu deux ans plus tard. Aujourd’hui nous voilà quasiment à C++20. ^^

Une petite question de puriste : si un invariant de classe n’est pas respecté et qu’on ne peut pas construire l’objet, on claque plutôt une exception ou une assertion ?

informaticienzero

Ton constructeur a des pré-conditions, ces pré-conditions doivent te garantir que tu peux construire l’objet. Si les préconditions ne sont pas respectées, c’est une assertion qu’on lève. Si par ailleurs un événement indépendant de notre volonté nous empêche de respecter l’invariant pendant le code de construction alors on aura une exception. Finalement, on peut ajouter une assertion en fin de constructeur pour s’assurer que l’on a fait notre job correctement et on pourra y vérifier l’invariant (s’il n’est pas vérifié, soit le code du constructeur est faux, soit le pré-conditions sont trop faibles).

Yeah… je me réveille après des mois. Et bravo!!!!


§ être un bon dév

a- Concernant les paradigmes. On peut dire que l’impératif est un paradigme qui donne des ordres. Son évolution naturelle fut le paradigme procédural qui permet de regrouper ces ordres en routines, appelées fonctions chez nous. L’immense majorité des langages utilisés couramment en industrie sont impérativo-procédurals. Même les langages OO (Java, C#) ont un coeur imp/proc.

Pour le fonctionnel, for-each n’est pas le meilleur exemple pour moi. find-if le serait peut-être plus. Voire, les range v2 vont encore plus loin. BTW, il a existé un langage OO à coeur fonctionnel: CLOS. Et j’ai envie de dire que Python a un bon mélange de tout ça. Bref, je m’égare.

b-

Simplement, l’un des attraits du C++ est cette permissivité.

"souplesse", non? Plutôt que permissivité.

c- A propos de paradigmes, je me souviens que "multi-paradigmes" est un terme qui ne plaît pas à B.Stroustrup car il donne envie de se restreindre à un paradigme à la fois — si mes souvenirs de ce qu’il disait sont bons.

d-

Si vous êtes vraiment bloqués sur un problème

Les exemple minimaux et complet (ECM) appartiennent à une démarche indispensable au passage. Non seulement c’est ce qui sera attendu par ceux pouvant répondre, cela les motivera à répondre plus vite avec un problème bien cerné, et surtout en cours de route, il y a toutes les chances que l’on trouve nous-même le problème ce qui booste l’égo/moral, et qui fait progresser.


§ lire la doc

e-

D’autres encore ont une garantie pas d’exception (no-throw guarantee). Aucune exception ne sera levée. Ces fonctions possèdent le mot-clef noexcept dans leur prototype.

Malheureusement pas :( Merci la règle de Lakos. Il y a eu une proposition dans le dernier mailing pour que les fonctions documentées sans exceptions mais avec un contrat narrow soient quand-même noexcept

f-

No exception safety

Si mes souvenirs sont bons cela veut dire que la fonction est bugguée. Et normalement, il ne devrait pas y en avoir dans la SL.

g-

Les chaînes de caractère au grand complet

caractères au pluriel

h- Doxygen

Je n’utilise jamais brief ou details. Je préfère utiliser l’option auto brief line, et laisse mon environnement de dev colorer correctement la brief line et le reste automatiquement — vim powa!

Pour les contrats, je les réserve plutôt aux contrats dynamiques, pas aux contrats statiques des concepts. Je mets ça dans la doc du tparam à la place.

@struct, @enum, @function n’ont aucun intérêt. Cela alourdit encore plus le cartouche doxygen.


§ compiler

i- _DEBUG est propre à visual. Le seul truc portable est NDEBUG qui est interprété pour garder ou inhiber les assertions.

j-

Une étape intermédiaire cachée

s/une/50/

En fait, même avant l’assembleur, il y a pas mal d’étapes intermédiaires au niveau de ce que l’on pourrait appeler abusivement: le middle-end. Dans le cas de clang -> LLVM-IR est pas mal documenté et source de nombreux articles. Le truc intéressant, c’est que les transformations au niveau du middle-end sont communes. Le front-end lui sera spécialisé par langages (C, C++, fortran, Rust…, go). Et le back-end est la dernière étape qui transforme en assembleur propre à la machine cible.

k- J’aurai introduit le terme unité de traduction. C’est un bon raccourci pour désigner le résultat de la précompilation. Et pour ensuite expliquer comment inline, les multiples définitions, le besoin de définition, les déclarations de choses en portée globale, etc s’articulent par rapport à ces unités de traduction.

l- un mot pour dire que l’on va avoir des modules et que l’on reverra le schéma à ce moment-là ?


§ debugguer.

D’abord bravo!

m- Un scénario type est de faire exploser les assertions et ensuite soit de jouer depuis le debuggueur, soit d’analyser un core-dumped dans le débuggueur. Les commandes bt/up/down et print sont fort pratiques à ce moment-là chez gdb p.ex.

§ Premiers pas OO

a- La première notion de service rejoint celle d'abstraction. Cette notion n’est pas propre à l’OO. D’ailleurs, FILE c’est abstrait, ça rend des services (via des fonctions libres), on ne sait pas comment c’est foutu. Les invariants sont protégés, sans même utiliser private.

b- IOW, les services ne sont pas limités aux seules fonctions membres. Cf le célèbre point de GOTW/XC++ au sujet de l’interface monolithique de std::string.

c- J’ai du mal à affirmer qu’aucun service n’est associé à int. Il y a des services qui font complètement abstraction du champs de bits sous-jacent de compléments à 2, de zero-initialisation…

d- Je n’aime carrément pas InformationPersonnelle::se_presenter(). On a un agrégat sans invariant et on lui rajoute une fonction d’affichage. Brrrrr.

On frôle le piège dans lequel tombe trop de cours d’OO: confondre BdD avec OO. Ici, je ne vois pas un vrai service OO — oui je sais, je me contredis p/r aux services d'int

e- Dans TC++PL, B. Stroustrup définit method comme définition alternative à virtual member function. C’est le seul à utiliser cette appellation. Mais historiquement, c’est son langage, il fait ce qu’il veut. Accessoirement en UML une méthode est une spécialisation d'opération, ce qui est loin d’être différent de la définition du TC++PL.

Bref, terme impropre que je préfère éviter.

Certains pinaillent maintenant sur attribut avec l’arrivé des attributs du C++11

f- L’invariant de la machine à café, c’est de ne pas faire de court-jus pour moi. Qu’il reste du café est une précondition à préparer le café.

g- A propos de fonctions qui peuvent être privés: il y a la réduction dans le cas des nombres rationnels. Elle peut ainsi servir à renforcer l’invariant à PGCD(d,r)==1 && d > 0.

h- Pour ce qui est d’avoir des attributs publics. Je dirai que par consistance, on évite de mélanger des attributs publics et des privés. Et que pour les agrégats (sans invariants), tout en public, ça marche très bien: nul besoin de faire semblant d’encapsuler quoique ce soit.

i- Le lancer d’exception dans le constructeur, je me dis de plus en plus que c’est en fait faire de la programmation défensive. En PpC, on aurait juste un report (sans adaptation ici) de l’invariant d != 0.


§ valeurs

j-

Rule of three

Historiquement, nous avons eu

  1. FCOC (Coplien — big four)
  2. big three, car OSEF du constructeur par défaut — mais j’en envie de dire, qu’il doit au moins y avoir un/des constructeurs qui toujours garantir le respect des invariants
  3. big two (cf article sur artima), car le RAII nous permet de nous passer du destructeur
  4. 0/5 et autres variantes comme le tout ou rien qui s’appliquent aussi aux entités. Pour les premiers il faudrait étendre la notion de définition à dire "qu’interdire c’est aussi définir" ce qui n’était historiquement pas le cas: comme des bourrins écervelés on définissait vraiment…

k- Dans mes formations j’ai fini par choisir de sortir la sémantique de mouvement du chapitre sur les valeurs. En effet, un ressource non copiable (mutex, fichier…), ça se déplace très bien. Pareil pour protected, l’héritage privé, et l’héritage multiple: c’est indépendant des 2 notions de valeur/entité.

l- Mon exo de matrice se résume à faire en sorte de supporter

Matrix id(3,3);
for (size_t i = 0; i != id.M() ; ++i)
    id(i,i) = 1;

Matrix a(3,3);
for (size_t i = 0; i != id.M() ; ++i)
    for (size_t ij= 0; j != id.N() ; ++j)
    id(i,j) = i+j;

std::cout << (a+id+a) << "\n";

C’est déjà un bon début. Après, il y a potentiellement 3 façons de faire (je raye d’emblée double**): double*, vector<double>, unique_ptr<double[]>. Chacune avec ses implications en terme de 0/2/5


§ Entités

m-

Héritage publique

s/publique/public

n- l’OCP est important, c’est le commencement de tout. On a une commonality (vocabulaire Multiparadigm Design de Jim O Coplien) et des points de variations (dynamiques dans notre cas OO), et on est capable de traiter de nouvelles situations sans avoir à modifier le code de la commonality. De façon totalement transparente, le système évolue naturellement: on lui plugge une nouvelle spécialisation, et on peut jouer — c’est plug’n’play!

Mon exemple: virer la poussière par terre depuis la mise en service de l’appareil, la collecte, l’élimination, et le rangement final que l’on ait balai, aspirateur, aspirateur centralisé, etc

En coup de vent parce que sur téléphone c’est pas pratique.

D’abord merci pour les retours.

On est d’accord, les services c’est pas que les fonctions membres. Je vais rajouter un encard précisant qu’on verra d’autres formes encore plus tard.

Pourquoi tu n’aimes pas se_presenter ? J’avoue que l’exemple n’est pas le meilleur qui soit, mais en quoi cette fonction est mal ? D’ailleurs, je ne cherche pas à présenter l’OO en faisant de la BDD mais simplement à démontrer qu’une structure peut avoir des fonctions membres, ce que le lecteur ne sait pas encore. :)

Pour le terme de méthode, je sais que Stroustrup n’aime pas, en C++ on n’aime pas trop non plus. Mais ça reste un terme très répandu dans le monde informatique, donc je me devais d’en toucher un mot.

Je n’aime pas se_presenter, car la classe ne fait vraiment rien à part balancer des choses sur la sortie standard, chose reconnue en plus comme de la mauvaise conception, et qu’il n’y a pas le moindre invariant.

Techniquement, oui on peut l’écrire, conceptuellement … bouaif.

Rien n’empêche de dire que "méthode" est un terme OO impropre en C++ et que le tuto emploiera "fonction membre" :p En info on parle aussi de procédures, de routine, de sous-programmes, pourtant aucun des termes n’est abordé. Pourquoi faire une exception pour méthode?

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