Partage
  • Partager sur Facebook
  • Partager sur Twitter

Besoin de conseils

Debutant en C++

    20 septembre 2007 à 13:10:53

    Bonjour a tous, j'aimerais si possible que vous jetiez un petit coup d'oeil a mon code, c'est un de mes premiers codes en C++ donc svp ne soyez pas trop critiques. J'aimerais en revanche beneficier de votre experience pour ameliorer mon code, corriger ses erreurs, ameliorer le style etc...

    En gros c'est un exercice a faire pour mon universite et ils ont beaucoup insiste sur les principes suivants : encapsulation, utilisation de const imperative dans les headers de fonction qui ne sont pas sensees modifier le code, etc.

    L'exercice est l'implementation d'une Liste Chainee d'objets string.

    Merci d'avance pour tous vos conseils, corrections ou autres!!

    MyLinkedList.h


    1. #ifndef _MyLinkedList_h
    2. #define _MyLinkedList_h
    3. class MyLinkedList
    4. {
    5.  public:
    6.     MyLinkedList();
    7.     ~MyLinkedList();
    8.     void Add (const std::string &toAdd);
    9.     bool Remove (const std::string &toRemove);
    10.     bool InList(const std::string &toSearch);
    11.     void PrintList() const;
    12.  private:
    13.     struct Node
    14.     {
    15.         std::string value;
    16.         Node *next;
    17.     };
    18.     Node *m_start;
    19. };
    20. #endif
    21. // Answer to question :
    22. // I indeed use a pointer to the next element.
    23. // We couldn't have used a reference instead of a pointer because a reference
    24. // needs to be initialized from the beginning.


    MyLinkedList.cpp


    1. #include <iostream>
    2. #include "MyLinkedList.h"
    3. // The constructor of the list.
    4. MyLinkedList::MyLinkedList()
    5. {
    6.     m_start = NULL;
    7. }
    8. // The destructor of the list.
    9. MyLinkedList::~MyLinkedList()
    10. {
    11.     while (m_start != NULL)
    12.     {
    13.         Node *p = m_start->next;
    14.         delete m_start;
    15.         m_start = p;
    16.     }
    17. }
    18. // Add an element to the end of the list and sets his next pointer to NULL.
    19. void MyLinkedList::Add(const std::string &toAdd)
    20. {
    21.     // If the element is in the list, won't do a thing.
    22.     if (InList(toAdd))
    23.         return;
    24.     // Reserve space for Node.
    25.     Node *temp = new Node;
    26.     // Assigns a copy of the toAdd string to the value of the node.
    27.     temp->value = std::string(toAdd);
    28.     temp->next = NULL;
    29.     // The list was empty.
    30.     if (m_start == NULL)
    31.         m_start = temp;
    32.     // There were already elements in the list, need to iterate till the end.
    33.     else
    34.     {
    35.         Node *temp2 = m_start;
    36.         while (temp2->next != NULL)
    37.         {
    38.             temp2 = temp2->next;
    39.         }
    40.         temp2->next = temp;
    41.     }      
    42. }
    43. // Remove an element from the list and returns true if the operation succeeded
    44. // (the element existed).
    45. // The tricky part of the implementation is to always keep a pointer to the
    46. // precedent element in order to set his next to the currentNode's next;
    47. bool MyLinkedList::Remove (const std::string &toRemove)
    48. {
    49.     // The element is not in the list.
    50.     if (!InList(toRemove))
    51.         return false;
    52.     Node *currentPointer, *previousPointer;
    53.     // For the first node there is not any pointer.
    54.     previousPointer = NULL;
    55.     // Visit each node, keeping a reference to the previous string each time.
    56.     for (currentPointer = m_start; currentPointer != NULL;
    57.          previousPointer = currentPointer,
    58.              currentPointer = currentPointer->next)
    59.     {
    60.         // We found the element to remove.
    61.         if (currentPointer->value == toRemove)
    62.         {
    63.             if (previousPointer == NULL)
    64.             {
    65.                 // We fix the beginning pointer.
    66.                 m_start = currentPointer->next;
    67.             }
    68.             else
    69.             {
    70.                 // Fix previous node's next to skip the element deleted.
    71.                 previousPointer->next = currentPointer->next;
    72.             }
    73.             delete currentPointer;
    74.             return true;
    75.         }
    76.     }
    77. }
    78. // Returns true if the given element is in the list, else false.
    79. bool MyLinkedList::InList(const std::string &toSearch)
    80. {
    81.     Node *current = m_start;
    82.     while (current != NULL)
    83.     {
    84.         if (current->value == toSearch)
    85.             return true;
    86.         current = current->next;
    87.     }
    88.     return false;
    89. }
    90. // Print the Linked List.
    91. // 2 possibilities : 1/ Empty list: print Empty.
    92. //                   2/ List not empty: print every elements (only one
    93. //                      per line).
    94. void MyLinkedList::PrintList() const
    95. {
    96.     Node *temp = m_start;
    97.     // The list is empty.
    98.     if (temp == NULL)
    99.     {
    100.         std::cout << "Empty\n";
    101.         return;
    102.     }
    103.     do
    104.     {
    105.         std::cout << temp->value << std::endl;
    106.         temp = temp->next;
    107.     }
    108.     while (temp!= NULL);
    109. }


    • Partager sur Facebook
    • Partager sur Twitter
      20 septembre 2007 à 13:30:38

      ca à l'air pas mal mais tu aurais pu te simplifier la vie avec
      1. using namespace std;

      met le au debut apres les includes
      (cela te permettera d'enlever les "std::")

      • Partager sur Facebook
      • Partager sur Twitter
        20 septembre 2007 à 16:10:55

        Je trouve que c'est très bien fait,

        passage de paramètre par références constantes c'est bon!

        Pour améliorer l'ajout tu peux créer un pointeur m_end qui conserverai la position du dernier élément et ainsi tu pourrais ajouter ton nouvel élément immédiatement après celui-ci.

        Pour la forme j'aurai créer une fonction empty() qui vérifierai si ma chaine contient au moins un élément.
        • Partager sur Facebook
        • Partager sur Twitter
          20 septembre 2007 à 22:27:27

          Merci beaucoup pour tes conseils je corrige ca de suite :)
          • Partager sur Facebook
          • Partager sur Twitter
            20 septembre 2007 à 22:41:08

            Côté encapsulation, il n'y a pas grand chose de fait.
            Tu peux déléguer une bonne partie de ton code aux noeuds. A commencer par un constructeur d'initialisation qui t'évitera d'accéder directement aux champs internes de ton noeud.

            En gros, des découpages (/raffinements) ont été oubliés :
            - construction des noeuds (donc)
            - recherche d'un noeud
            • Partager sur Facebook
            • Partager sur Twitter
            C++: Blog|FAQ C++ dvpz|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS| Bons livres sur le C++| PS: Je ne réponds pas aux questions techniques par MP.
              23 septembre 2007 à 15:33:01

              Citation : neuneutrinos

              tu aurais pu te simplifier la vie en utilisant using namespace std;


              Encombrer l'espace de nom global est généralement une mauvaise idée. On fait ça pour simplifier des codes d'exemple, mais en règle générale c'est très déconseillé.
              • Partager sur Facebook
              • Partager sur Twitter

              Besoin de conseils

              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
              • Editeur
              • Markdown