Підхід , який ви описуєте сумісний не тільки з C ++, але і з його ( в основному) мови підмножина C . Навчитися розробляти пов'язаний список у стилі С - це хороший спосіб познайомитись із методами програмування низького рівня (наприклад, ручним управлінням пам'яттю), але це, як правило, не найкраща практика для сучасної розробки C ++.
Нижче я реалізував чотири варіанти, як керувати списком елементів у C ++.
raw_pointer_demoвикористовує той же підхід, що і ваш - ручне управління пам’яттю, необхідне з використанням необроблених покажчиків. Використання C ++ тут стосується лише синтаксичного цукру , а застосовуваний підхід інакше сумісний з мовою С.
- У
shared_pointer_demoсписку управління все ще виконується вручну, але управління пам'яттю є автоматичним (не використовує необроблені покажчики). Це дуже схоже на те, що ви, напевно, відчували з Java.
std_list_demoвикористовує listконтейнер стандартної бібліотеки . Це показує, як набагато простіше, якщо ви покладаєтесь на існуючі бібліотеки, а не на власній власній бібліотеці.
std_vector_demoвикористовує vectorконтейнер стандартної бібліотеки . Це управляє сховищем списку в одному суміжному виділенні пам'яті. Іншими словами, немає покажчиків на окремі елементи. У деяких досить екстремальних випадках це може стати значно неефективним. Однак для типових випадків це рекомендована найкраща практика управління списками на C ++ .
Зауважимо: з усього цього лише raw_pointer_demoфактично потрібно, щоб список було явно знищено, щоб уникнути "протікання" пам'яті. Інші три методи автоматично знищують список та його вміст, коли контейнер виходить із сфери застосування (після завершення функції). Сенс у тому, що C ++ може бути дуже «подібним до Java» у цьому плані - але лише якщо ви вирішите розробити свою програму, використовуючи інструменти високого рівня, що є у вашому розпорядженні.
/*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();
}