User Tools

Site Tools


in202:seance_1:td_1

This is an old revision of the document!


TD : Premiers pas avec C++

Première Partie :Installation d'un environnement C++

Etape 1 : Installation de l'environnement

En vous référant à la documentation disponible sous ce lien et en n'hésitant pas à demander à l'enseignant de vous accompagner, installer un environnement de développement sur votre ordinateur.

Etape 2 : Compilation d'un exemple simple de classe C++

En fonction de l'environnement, essayer de créer un projet “console” et ensuite ajouter le code suivant dans ce projet.

Assurez vous que le projet compile et s'exécute correctement.

Seconde partie : Création d'une classe "Compteur" en C++

Question 2.1 :

Créer un projet “console” vide dans votre environnement de développement.

Question 2.2 :

Ajoutez un fichier Counter.h ou Counter.hpp ou Counter.hh dans votre fichier et introduisez la structure de la classe Counter dans ce fichier.

class MyCounter
{
public:
    unsigned counter;
    unsigned max; 
};

Question 2.3 :

Ajoutez les fonctions membres à votre compteur :

class MyCounter
{
public:
 
    ...
 
    void increment() {
      counter ++;
      if(counter > max)
        counter = 0;
    }
 
    void reset() {
      counter = 0;
    }
};

Expliquer ce que font ces fonctions membres.

Question 2.4 :

Testez le code avec le programme main.cpp suivant :

#include<iostream>
#include "counter.hpp"
 
void testCounter()
{
  MyCounter counterA;
  counterA.counter = 0;
  counterA.max = 2;
 
  MyCounter counterB;
  counterB.counter = 0;
  counterB.max = 4;
 
  for(int i = 0; i < 4; i++)
  {
      std::cout << "compteur A: (" << counterA.counter << ", " << counterA.max << ")" << std::endl;
      std::cout << "compteur B: (" << counterB.counter << ", " << counterB.max << ")" << std::endl;
      counterA.increment();
      counterB.increment();
  }
}
 
int main()
  testCounter();
  return 0;
}

Expliquer le comportement des compteurs.

Troisième partie : Les constructeurs

Nous voyons dans le code précédent que nous créons un compteur et que nous l'initialisation en mettant à jour les valeurs counter et max.

Cependant, ceci n'est pas optimal pour plusieurs raisons:

  • nous avons un objet qui n'a pas été initialisé du tout.
  • nous avons un objet qui peut-être partiellement initialisé, seul le champ max ou le champ counter a été initialisé,
  • nous avons un objet qui est mal initialisé, par exemple la valeur du chmap max est inférieur à la valeur du counter, ce qui ne doit jamais se produire.

Question 3.1

Vérifier le problème de la mauvaise initialisation d'un objet en exécutant le code suivant.

void createArrayOfCounters()
{
    MyCounter counters[4];
    for(int i = 0, i < 4; i ++)
      std::cout << i << " : " << counters[i].counter << "/" << counters[i].max << std::endl;
}
 
void main()
{
  createArrayOfCounters();
  return 0;
}

Question 3.2

Proposer des constructeurs pour les compteurs pour s'assurer que le compteur est bien initialisé.

On proposera au moins deux constructeurs :

  • un constructeur qui met counter à 0 et max à une valeur maximale passée en paramètre et strictement supérieure à 0,
  • un constructeur qui met counter et max à des valeurs passées en paramètre. Cependant si counter est supérieur à max on met counter à 0.

Question 3.2.1

Ajouter ces constructeurs à votre classe.

Question 3.2.2

Modifier la fonction testCounter pour utiliser ces constructeurs afin de créer et d'initialiser les objets counterA et counterB.

Quatrième partie : Rendre publique/privée des champs et fonctions

Nous voyons bien que les champs counter, max sont des champs qui ne devraient pas pouvoir être modifié accidentellement puisque cela modifie le comportement du compteur. Par exemple, le code suivant conduit à un comportement erratique :

int main()
{
  MyCounter counterA;
  counterA.counter = 0;
  counterA.max = 10;
 
 
  for(int i = 0; i < 4; i++)
  {
      std::cout << "compteur A: (" << counterA.counter << ", " << counterA.max << ")" << std::endl;
      counterA.increment();
      counterA.max -= 2;
  }
  return 0;

Dans ce cas, il faut rendre les champs uniquement accessible en lecture et non pas en lecture et écrire. Pour ce faire, il suffit de :

  • rendre les champs privés (on doit transformer la déclaration de l'objet MyCounter de struct en class.
  • définir dans cette classe au moins une section public et une section private:
        class MyCounter
        {
            private:
              ... // section privée
            public:
              ... // section publique
        };
  • mettre les champs privés et définir des fonctions pour accéder aux valeurs. Nous appellons ces fonctions des accesseurs. Souvent en lecture elle commence par get suivit du nom de la variable, en écriture, par set et le nom de la variable. Ici, nous proposons de définir les fonctions getCounter et getMax qui elles seront publiques.

Question 4.1

Modifier votre classe en rendant les champs max et counter privés et en déclarant des méthodes d'accès getCounter et getMax.

Question 4.2

Question 4.2.1

Vérifier que la compilation de la fonction testCounter génère des erreurs.

Question 4.3

Modifier la fonction testCounter pour désormais appeller les méthodes d'accès. Vérifier le bon fonctionnement de la fonction testCounter.

in202/seance_1/td_1.1616326819.txt.gz · Last modified: 2021/03/21 11:40 by bmonsuez