Protection des classes et des données.

Protection des classes et des données à la compilation.

const

Voir version :

Pas de dépendances

Télécharger :

class test
{
private:
    int x;
public:
    test(){}
    char* fonc(int a);
    void fonc2(int* b);
    void fonc3(int& d);
};

char* test::fonc(int a) 
{
    x=a;  // 1
    a++;  // 2
    return "plouf";
}

void test::fonc2(int* b)
{
    *b = 5; // 3
    b++;    // 4
}

void test::fonc3(int& d)
{
    d=6;  // 5
}

int main()
{
    int table[3];
    int c = 5; 
    c=c+1;  // 6
    char* paf;
        
    table[0]=7;
    table[1]=13;
    table[2]=21;
    
    test t;
    paf=t.fonc(6);
    t.fonc2(&(table[0]));

    paf[0]='V';  // 7

    t.fonc3(c);

    return 0;
}





Commentaires


  Ce tutorial - non fondamental - que je replacerai a la fin de la partie C++ - illustre les sécurités sur const
  Ces sécurités sont des protections en écriture : le but est de se garantir qu'il n'y aura pas de modification spécifique
  dans une fonction, sans meme savoir ce qu'il y adedans.

  La sécurité se fait juste au niveau de la compilation. Inutile de lancer le programme, essayez juste de le compiler.

  Par défaut, ça compile bien.

Maintenant, on va faire des modifications :

PROTECTION DES DONNEES MEMBRES :
******************************** 

  remplacez :

  char* fonc(int a);

  par

  char* fonc(int a) const

  (adaptez dans l'implémentation bien sur !!)

  Compilez : ça geule au signet 1, alors que la méthode essaie de modifier la données membre x.
  En effet, mettre const a la sortie d'une méthode assure qu'elle ne modifiera pas les données membres.

  C'est une garantie pour celui qui appelle la méthode, il sait que son instance ne sera pas modifiée.

PROTECTION DES PARAMETRES :
***************************

  Cette fois, adaptez fonc a la syntaxe suivante :

  char* test::fonc(const int a)

  Cette fois, ça gueule sur le label 2, quand fonc essaie de modifier a.

  C'est une sécurité pour celui qui implémente la méthode fonc
  mais également une sécurité si vous appelez a par référence :

  char* test::fonc(const int& a)

  dans ce cas c'est une sécurité également pour celui qui appelle la fonction, il est sur que sa variable passée
  par référence ne sera pas modifiée.

PROTECTION DES CODES DE RETOUR :
********************************

  Adaptez fonc a la syntaxe suivante :

  const char* test::fonc(int a) 

  Adaptez également la définition du main de la façon suivante :
  
  const char* paf;

  Cette fois, ça gueule au label 7 : ce const certifie que la chaine passée en retour ne sera pas modifiée.

PROTECTION DES POINTEURS :
**************************
2 cas :

cas écriture sous pointeur :
----------------------------

  Remplacez fonc2 par :
  
  void fonc2(const int* b);

  void fonc2(int const * b);

  au choix : les 2 syntaxes sont acceptées.

  Cette fois, ça gueule au label 3 :

  Cette syntaxe interdit simplement de modifier ce qu'il y a en dessous d'un pointeur.

cas déplacement de pointeur :
----------------------------

  Remplacez fonc2 par :

  void fonc2(int* const b);

  Cette fois, c'est au label 4 que ça gueule. Vous ne pouvez pas déplacer le pointeur.

combiné :
---------

  Remplacez fonc2 par :


  void fonc2(const int* const b);
  
  ou
	
  void fonc2(int const * const b);

  Cette fois, ça gueule au 3 et au 4 : vous bloquez non seulement l'écriture sous pointeur, mais le déplacement.


PROTECTION DES PARAMETRES ET CONSTANTES
***************************************

  Un peu comme vu plus haut, adaptez fonc 3 ainsi :
  
  void fonc3(const int& d);

  ça gueule au label 5.

  Essayez maintenant, dans le main, de faire :

  t.fonc3(18);  // passer une constante pure.

  Avec la syntaxe :

  void fonc3(const int& d);

  ça passe, car vous passez 18 en tant que constante, donc c'est bon

  Avec la syntaxe :

  void fonc3(int& d);

  ça gueule, car vous passez 18 en tant que reference, sans protection en écriture, donc il est susceptible d'etre modifié,
  ce qui est impensable pour ue constante balancée comme dans le code en dur.


PROTECTION A L'INITIALISATION :
*******************************

  dans le main, déclarez la variable c ainsi.

  const int c = 5; 

  ça marche un peu comme un #define c 5

  vous ne pourrez jamais modifier c : ça gueule au label 6

  Evidemment, il faut assigner une valeur de départ, si vous faites juste 

  const int c;  

  il vous dira que ce n'est pas bon, qu'il faut initialiser.




Voila les cas tordus de const, j'espere ne pas en avoir oublié :)

Note : mettre des const ou pas de const ne joue pas du tout sur l'éxecution du programme :
tout se passe a la compilation. Dans le programme, une fois compilé, il n'y a plus du tout de notion de const,
c'est juste pour protéger le programmeur (ou pour l'emmerder, ça dépend des points de vue)