User Tools

Site Tools


in204:tds:sujets:td8:part2

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
in204:tds:sujets:td8:part2 [2020/11/02 16:18]
bmonsuez [Question 2]
in204:tds:sujets:td8:part2 [2022/11/18 10:49] (current)
Line 1: Line 1:
-====== ​Section critique ​======+====== ​Partie II – Destructeurs ​======
  
-[[in204:tds:​sujets:​td8|TD8]]+Nous créons les classes suivantes ​:
  
-===== Références=====+<code cpp> 
 +class GraphicalObject  
 +
 +    public: ​       
 +       ​virtual void draw () const 0 ;  
 +       ​~GraphicalObject() { std::cout << "& Delete GraphicalObject \n"; } 
 +        
 +};
  
-[[http://​en.cppreference.com/​w/​cpp/​thread/​unique_lock|std::unique_lock]] +class Linepublic GraphicalObject  
-[[http://​en.cppreference.com/​w/​cpp/​thread/​mutex|std::mutex]]+
 +    public: 
 +       ​virtual void draw () const { std::cout << "​Line";​ } ;  
 +       ~Line() { std::cout << "​Delete Line\n";​ } 
 +        
 +};
  
-===== Question n°1===== ​+class Circle: public GraphicalObject  
 +
 +    public: 
 +       ​virtual void draw() const { std::cout << " Circle";​ } ;  
 +       ​~Circle ​ () { std::cout << "​Delete Circle ​ \n"; } 
 +       
 +}; 
 +</​code>​
  
-Nous supposons que nous avons deux fonctions, une première fonction calcule la valeur maximale ​d’un tableau numérique ​:+ 
 +Nous créons le tableau ​d’objet suivant ​:
  
 <code cpp> <code cpp>
-void array_find_max(const ​std::​vector<​int>& theArray, ​int* theMaxValue+std::​vector<​GraphicalObject*createGraphicalObjects( 
-!+    ​int theSize
- int result = theArray[0]+
- for (int i = 1; i < (int)theArray.size(); i++) +    ​std::​vector<​GraphicalObject*>​ graphicalObjects(theSize)
-+    for(int i=0; i < size; i++) 
- if (theArray[i] > result+    
- result = theArray[i]; +       graphicalObjects[i] = new Line(); 
-+       graphicalObjects[++i] = new Circle()
- *theMaxValue = result;+    
 +    ​return graphicalObjects;
 } }
 </​code>​ </​code>​
  
-la seconde ​fonction ​modifie ​le tableau ​en multipliant chaque valeur numérique du tableau par 2 :+Nous définissons une fonction ​de dessin pour l'​ensemble des éléments  
 +dans le tableau.
  
 <code cpp> <code cpp>
-void array_multiply_by(std::​vector<​int>& ​theArray, int theValue)+ 
 +void drawGraphicalObjects(std::​vector<​GraphicalObject*>& ​theGraphicalObjects)
 { {
- for (int i 1theArray.size(); i++) +    ​for(auto it theGraphicalObjects.begin() 
- theArray[i] ​*= theValue;+        it theGraphicalObjects.end(); it++) 
 +    { 
 +       (*it)->​draw(); 
 +    }
 } }
 </​code>​ </​code>​
  
-Ecrire chacune des fonctions. 
  
-===== Question 2 =====  ​ 
- 
-Nous souhaitons exécuter en parallèle les deux fonctions. ​ 
- 
-Exécuter plusieurs fois ces fonctions sur un tableau de grande taille que vous créez soit de manière aléatoire soit de manière cycliques. Ci-dessous quelques exemples de fonctions générant des tableaux de taille ''​n''​ et ayant comme valeur des nombres entre ''​0''​ et ''​theMaxValue''​. 
  
 +Nous créons la fonction de destruction du tableau suivante:
 <code cpp> <code cpp>
-void initialize_array(std::​vector<​int>& ​theArray, int theSize, + 
- int theMaxValue)+void deleteGraphicalObjects(std::​vector<​GraphicalObject*>& ​theGraphicalObjects)
 { {
- theArray.clear(); +    for(auto it = theGraphicalObjects.begin();  
- int step = theMaxValue / 3; +        it < theGraphicalObjects.end()it++) 
- theArray[0] = 0; +    { 
- for (int i = 1i < theSize; i++) +       ​delete *it; 
- theArray[i] = (theArray[i-1] + step) % (theMaxValue + 1);+    }
 } }
 </​code>​ </​code>​
-Ou + 
 +Et nous testons avec le code suivant :
  
 <code cpp> <code cpp>
-#​include<​random>​ 
  
-void initialize_random_array(std::​vector<​int>&​ theArray, int theSize, +auto graphicalObjects = createGraphicalObjects(10); 
- int theMaxValue) +drawGraphicalObjects(graphicalObjects); 
-+deleteGraphicalObjects(graphicalObjects); 
- static std::​mt19937 gen(1729); +
- std::​uniform_int_distribution<>​ distrib(0, theMaxValue); +
- theArray.clear();​ +
- for (int i = 0; i < theSize; i++) +
- theArray[i] = distrib(gen); +
-}+
 </​code>​ </​code>​
  
-Expliquer pourquoi les résultats ne sont pas toujours cohérents ? ie. que la valeur maximale retournée est supérieure à la valeur maximale du tableau spécifiée au montant de sa création.+===== Question n°1 =====
  
-===== Question n°3 ===== +Justifier la sortie produite à l’écran ? Est-ce que c’est le comportement désiré ?
  
-Il faut utiliser un verrou qui permet à une méthode de se garantir l’exclusivité de l’usage du tableau. Pour ce faire, nous pouvons utiliser un objet std::mutex qui encapsule un mécanisme d’exclusion mutuelle. +<hidden Correction>​
-L’objet [[http://​en.cppreference.com/​w/​cpp/​thread/​unique_lock|std::​unique_lock]] permet d’obtenir un accès exclusif sur un object [[http://​en.cppreference.com/​w/​cpp/​thread/​mutex|std::​mutex]]. Quand nous écrivons le code suivant :+
  
-<code cpp> +Le destructeur appellé est celui de l'​objet de base. Nous souhaitons appeller le destructeur de l'​objet véritablement détruit et non celui de l'​objet de base.
-#include <​iostream> ​      // std::cout +
-#include <​thread> ​        // std::​thread +
-#include <​mutex> ​         // std::mutex, std::​unique_lock+
  
-std::mutex mtx;           // mutex fournissant le mécanisme d’exclusion mutuelle.+</hidden>
  
-void my_function (int n, char c) { +===== Question n°2 =====
- // section critique, tant que l'​objet lck existe, personne ne pourra +
- // accéder à mtx. +
- std::​unique_lock<​std::​mutex>​ lck(mtx); +
- // Code s'​exécutant. +
-+
-</​code>​+
  
-==== Question n°3.1 ====  +Proposer une modification pour obtenir le comportement souhaité.  
-Modifier les fonctions ​ + 
-<code cpp> +Tester après cette modification. 
-int array_find_max(std::​vector<​int>&​ theArray, int* theMaxValue) + 
-</code>+<hidden Correction> 
 + 
 +Nous déclarons le destructeur dans la classe de base comme étant virtuel.
  
-et  
  
 <code cpp> <code cpp>
-void array_multiply_by(std::vector<int>theArray, int theValue) +class GraphicalObject  
-</​code>​ +
-pour implanter le mécanisme d’exclusion mutuelle propose.+    public: ​       
 +       ​virtual ​void draw () const = 0 ;  
 +       ​~GraphicalObject() { std::cout << "Delete GraphicalObject \n"; } 
 +       ​ 
 +};
  
-==== Question n°3.2 ==== +class Line: public GraphicalObject ​ 
-Exécuter le code et vérifier que les résultats sont dorénavant cohérents.+
 +    public: 
 +       ​virtual void draw () const { std::cout << "​Line";​ } ;  
 +       ​~Line() { std::cout << "​Delete Line\n";​ } 
 +        
 +};
  
 +class Circle: public GraphicalObject ​
 +{
 +    public:
 +       ​virtual void draw() const { std::cout << " Circle";​ } ; 
 +       ​~Circle ​ () { std::cout << "​Delete Circle ​ \n"; }
 +      ​
 +};
 +</​code>​
  
 +Désormais, c'est bien le destructeur de l'​objet qui est détruit qui est appellé et pas uniquement le destructeur de la classe de base.
  
 +</​hidden>​
  
in204/tds/sujets/td8/part2.1604333927.txt.gz · Last modified: 2020/11/02 16:18 by bmonsuez