A abordagem que você descreve é compatível não apenas com C ++, mas também com a sua (principalmente) linguagem subconjunto C . Aprender a desenvolver uma lista vinculada no estilo C é uma boa maneira de se apresentar a técnicas de programação de baixo nível (como gerenciamento manual de memória), mas geralmente não é uma prática recomendada para o desenvolvimento moderno de C ++.
Abaixo, implementei quatro variações de como gerenciar uma lista de itens em C ++.
raw_pointer_demo
usa a mesma abordagem que a sua - gerenciamento manual de memória necessário com o uso de ponteiros brutos. O uso de C ++ aqui é apenas para açúcar sintático , e a abordagem usada é compatível com a linguagem C.
- Na
shared_pointer_demo
lista, o gerenciamento ainda é feito manualmente, mas o gerenciamento de memória é automático (não usa ponteiros brutos). Isso é muito semelhante ao que você provavelmente já experimentou com Java.
std_list_demo
usa o list
contêiner da biblioteca padrão . Isso mostra como as coisas ficam mais fáceis se você confiar nas bibliotecas existentes, em vez de criar suas próprias.
std_vector_demo
usa o vector
contêiner da biblioteca padrão . Isso gerencia o armazenamento da lista em uma única alocação de memória contígua. Em outras palavras, não há indicadores para elementos individuais. Para certos casos bastante extremos, isso pode se tornar significativamente ineficiente. Para casos típicos, no entanto, essa é a melhor prática recomendada para o gerenciamento de listas em C ++ .
Nota: De todos esses itens, apenas os que raw_pointer_demo
realmente exigem que a lista seja destruída explicitamente para evitar "vazamento" de memória. Os outros três métodos destruiriam automaticamente a lista e seu conteúdo quando o contêiner ficar fora do escopo (na conclusão da função). O ponto é: o C ++ é capaz de ser muito "semelhante ao Java" a esse respeito - mas somente se você optar por desenvolver seu programa usando as ferramentas de alto nível à sua disposição.
/*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();
}