Der Ansatz, den Sie beschreiben , ist kompatibel nicht nur mit C ++, sondern auch mit seiner (meist) Teilmenge Sprache C . Das Erlernen der Entwicklung einer verknüpften Liste im C-Stil ist eine gute Möglichkeit, sich mit einfachen Programmiertechniken (z. B. manueller Speicherverwaltung) vertraut zu machen, ist jedoch im Allgemeinen keine bewährte Methode für die moderne C ++ - Entwicklung.
Im Folgenden habe ich vier Varianten zum Verwalten einer Liste von Elementen in C ++ implementiert.
raw_pointer_demo
Verwendet den gleichen Ansatz wie Sie - manuelle Speicherverwaltung bei Verwendung von Rohzeigern erforderlich. Die Verwendung von C ++ ist hier nur für syntaktischen Zucker , und der verwendete Ansatz ist ansonsten mit der C-Sprache kompatibel.
- In
shared_pointer_demo
der Liste erfolgt die Verwaltung weiterhin manuell, die Speicherverwaltung erfolgt jedoch automatisch (verwendet keine Rohzeiger). Dies ist sehr ähnlich zu dem, was Sie wahrscheinlich mit Java erlebt haben.
std_list_demo
verwendet den Standardbibliothekscontainer list
. Dies zeigt, wie viel einfacher es wird, wenn Sie sich auf vorhandene Bibliotheken verlassen, anstatt Ihre eigenen zu rollen.
std_vector_demo
verwendet den Standardbibliothekscontainer vector
. Dies verwaltet den Listenspeicher in einer einzigen zusammenhängenden Speicherzuordnung. Mit anderen Worten, es gibt keine Zeiger auf einzelne Elemente. In bestimmten extremen Fällen kann dies erheblich ineffizient werden. In typischen Fällen ist dies jedoch die empfohlene Best Practice für die Listenverwaltung in C ++ .
Bemerkenswert: Von all diesen raw_pointer_demo
erfordert nur das tatsächlich, dass die Liste explizit zerstört wird, um ein "Verlieren" des Speichers zu vermeiden. Die anderen drei Methoden würden die Liste und ihren Inhalt automatisch zerstören, wenn der Container den Gültigkeitsbereich verlässt (am Ende der Funktion). Der Punkt ist: C ++ kann in dieser Hinsicht sehr "Java-ähnlich" sein - aber nur, wenn Sie Ihr Programm mit den verfügbaren High-Level-Tools entwickeln.
/*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();
}