Cách tiếp cận mà bạn mô tả không chỉ tương thích với C ++ mà còn với (chủ yếu) ngôn ngữ con C của nó . Học cách phát triển danh sách liên kết kiểu C là một cách tốt để giới thiệu bản thân với các kỹ thuật lập trình cấp thấp (chẳng hạn như quản lý bộ nhớ thủ công), nhưng nói chung nó không phải là phương pháp hay nhất để phát triển C ++ hiện đại.
Dưới đây, tôi đã triển khai bốn biến thể về cách quản lý danh sách các mục trong C ++.
raw_pointer_demo
sử dụng phương pháp tương tự như của bạn - cần quản lý bộ nhớ thủ công với việc sử dụng các con trỏ thô. Việc sử dụng C ++ ở đây chỉ dành cho cú pháp-đường và cách tiếp cận được sử dụng tương thích với ngôn ngữ C.
- Trong
shared_pointer_demo
danh sách quản lý vẫn được thực hiện thủ công, nhưng quản lý bộ nhớ là tự động (không sử dụng con trỏ thô). Điều này rất giống với những gì bạn có thể đã trải qua với Java.
std_list_demo
sử dụng vùng list
chứa thư viện tiêu chuẩn . Điều này cho thấy mọi thứ trở nên dễ dàng hơn bao nhiêu nếu bạn dựa vào các thư viện hiện có hơn là sử dụng thư viện của riêng bạn.
std_vector_demo
sử dụng vùng vector
chứa thư viện tiêu chuẩn . Điều này quản lý việc lưu trữ danh sách trong một phân bổ bộ nhớ liền kề. Nói cách khác, không có con trỏ đến các phần tử riêng lẻ. Đối với một số trường hợp khá khắc nghiệt, điều này có thể trở nên kém hiệu quả đáng kể. Tuy nhiên, đối với các trường hợp điển hình, đây là phương pháp hay nhất được khuyến nghị để quản lý danh sách trong C ++ .
Lưu ý: Trong số tất cả những điều này, chỉ có điều raw_pointer_demo
thực sự yêu cầu danh sách được hủy một cách rõ ràng để tránh "rò rỉ" bộ nhớ. Ba phương thức khác sẽ tự động hủy danh sách và nội dung của nó khi vùng chứa vượt ra khỏi phạm vi (ở phần kết của hàm). Vấn đề là: C ++ có khả năng rất giống Java về mặt này - nhưng chỉ khi bạn chọn phát triển chương trình của mình bằng cách sử dụng các công cụ cấp cao theo ý của bạn.
/*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();
}