L'approche que vous décrivez est compatible non seulement avec C ++, mais aussi avec son langage sous - ensemble ( la plupart du temps) C . Apprendre à développer une liste chaînée de style C est un bon moyen de vous familiariser avec les techniques de programmation de bas niveau (comme la gestion manuelle de la mémoire), mais ce n'est généralement pas le cas. une bonne pratique pour le développement C ++ moderne.
Ci-dessous, j'ai implémenté quatre variantes sur la façon de gérer une liste d'éléments en C ++.
raw_pointer_demo
utilise la même approche que la vôtre - la gestion manuelle de la mémoire requise avec l'utilisation de pointeurs bruts. L'utilisation de C ++ ici est uniquement pour le sucre syntaxique , et l'approche utilisée est par ailleurs compatible avec le langage C.
- Dans
shared_pointer_demo
la liste, la gestion se fait toujours manuellement, mais la gestion de la mémoire est automatique (n'utilise pas de pointeurs bruts). Ceci est très similaire à ce que vous avez probablement expérimenté avec Java.
std_list_demo
utilise le list
conteneur de bibliothèque standard . Cela montre à quel point les choses deviennent plus faciles si vous comptez sur des bibliothèques existantes plutôt que sur la vôtre.
std_vector_demo
utilise le vector
conteneur de bibliothèque standard . Cela gère le stockage de la liste dans une seule allocation de mémoire contiguë. En d'autres termes, il n'y a pas de pointeurs vers des éléments individuels. Dans certains cas plutôt extrêmes, cela peut devenir considérablement inefficace. Dans les cas typiques, cependant, il s'agit de la meilleure pratique recommandée pour la gestion des listes en C ++ .
À noter: De tous ces éléments, seul le raw_pointer_demo
requiert en fait que la liste soit explicitement détruite afin d'éviter une «fuite» de mémoire. Les trois autres méthodes détruiraient automatiquement la liste et son contenu lorsque le conteneur sort du cadre (à la fin de la fonction). Le fait est que C ++ est capable d'être très "Java" à cet égard - mais seulement si vous choisissez de développer votre programme en utilisant les outils de haut niveau à votre disposition.
/*BINFMTCXX: -Wall -Werror -std=c++11
*/
#include <iostream>
#include <algorithm>
#include <string>
#include <list>
#include <vector>
#include <memory>
using std::cerr;
/** Brief Create a list, show it, then destroy it */
void raw_pointer_demo()
{
cerr << "\n" << "raw_pointer_demo()..." << "\n";
struct Node
{
Node(int data, Node *next) : data(data), next(next) {}
int data;
Node *next;
};
Node * items = 0;
items = new Node(1,items);
items = new Node(7,items);
items = new Node(3,items);
items = new Node(9,items);
for (Node *i = items; i != 0; i = i->next)
cerr << (i==items?"":", ") << i->data;
cerr << "\n";
// Erase the entire list
while (items) {
Node *temp = items;
items = items->next;
delete temp;
}
}
raw_pointer_demo()...
9, 3, 7, 1
/** Brief Create a list, show it, then destroy it */
void shared_pointer_demo()
{
cerr << "\n" << "shared_pointer_demo()..." << "\n";
struct Node; // Forward declaration of 'Node' required for typedef
typedef std::shared_ptr<Node> Node_reference;
struct Node
{
Node(int data, std::shared_ptr<Node> next ) : data(data), next(next) {}
int data;
Node_reference next;
};
Node_reference items = 0;
items.reset( new Node(1,items) );
items.reset( new Node(7,items) );
items.reset( new Node(3,items) );
items.reset( new Node(9,items) );
for (Node_reference i = items; i != 0; i = i->next)
cerr << (i==items?"":", ") << i->data;
cerr<<"\n";
// Erase the entire list
while (items)
items = items->next;
}
shared_pointer_demo()...
9, 3, 7, 1
/** Brief Show the contents of a standard container */
template< typename C >
void show(std::string const & msg, C const & container)
{
cerr << msg;
bool first = true;
for ( int i : container )
cerr << (first?" ":", ") << i, first = false;
cerr<<"\n";
}
/** Brief Create a list, manipulate it, then destroy it */
void std_list_demo()
{
cerr << "\n" << "std_list_demo()..." << "\n";
// Initial list of integers
std::list<int> items = { 9, 3, 7, 1 };
show( "A: ", items );
// Insert '8' before '3'
items.insert(std::find( items.begin(), items.end(), 3), 8);
show("B: ", items);
// Sort the list
items.sort();
show( "C: ", items);
// Erase '7'
items.erase(std::find(items.begin(), items.end(), 7));
show("D: ", items);
// Erase the entire list
items.clear();
show("E: ", items);
}
std_list_demo()...
A: 9, 3, 7, 1
B: 9, 8, 3, 7, 1
C: 1, 3, 7, 8, 9
D: 1, 3, 8, 9
E:
/** brief Create a list, manipulate it, then destroy it */
void std_vector_demo()
{
cerr << "\n" << "std_vector_demo()..." << "\n";
// Initial list of integers
std::vector<int> items = { 9, 3, 7, 1 };
show( "A: ", items );
// Insert '8' before '3'
items.insert(std::find(items.begin(), items.end(), 3), 8);
show( "B: ", items );
// Sort the list
sort(items.begin(), items.end());
show("C: ", items);
// Erase '7'
items.erase( std::find( items.begin(), items.end(), 7 ) );
show("D: ", items);
// Erase the entire list
items.clear();
show("E: ", items);
}
std_vector_demo()...
A: 9, 3, 7, 1
B: 9, 8, 3, 7, 1
C: 1, 3, 7, 8, 9
D: 1, 3, 8, 9
E:
int main()
{
raw_pointer_demo();
shared_pointer_demo();
std_list_demo();
std_vector_demo();
}