설명하는 접근 방식은 C ++뿐만 아니라 (대부분) 하위 집합 언어 C 와도 호환됩니다 . C 스타일 연결 목록을 개발하는 방법을 배우는 것은 저수준 프로그래밍 기술 (예 : 수동 메모리 관리)을 소개하는 좋은 방법이지만 일반적으로 최신 C ++ 개발을위한 최선의 방법 은 아닙니다 .
아래에서는 C ++에서 항목 목록을 관리하는 방법에 대해 네 가지 변형을 구현했습니다.
raw_pointer_demo
당신과 동일한 접근 방식을 사용합니다-원시 포인터 사용에 필요한 수동 메모리 관리. 여기서 C ++의 사용은 syntactic-sugar 에만 해당되며 사용 된 접근 방식은 C 언어와 호환됩니다.
- 에서
shared_pointer_demo
목록 관리는 여전히 수동으로 수행되지만, 메모리 관리는 자동 (원시 포인터를 사용하지 않습니다). 이것은 아마도 Java에서 경험 한 것과 매우 유사합니다.
std_list_demo
표준 라이브러리 list
컨테이너를 사용합니다 . 이것은 자신의 라이브러리를 롤링하지 않고 기존 라이브러리에 의존하는 경우 얼마나 쉽게 얻을 수 있는지 보여줍니다.
std_vector_demo
표준 라이브러리 vector
컨테이너를 사용합니다 . 이것은 단일 연속 메모리 할당에서 목록 저장소를 관리합니다. 즉, 개별 요소에 대한 포인터가 없습니다. 다소 극단적 인 경우에는 상당히 비효율적 일 수 있습니다. 그러나 일반적인 경우에는 이것이 C ++의 목록 관리에 권장되는 모범 사례입니다 .
참고 :이 모든 것 중에서 raw_pointer_demo
실제로 "누수"메모리를 피하기 위해 목록을 명시 적으로 삭제해야합니다. 다른 세 가지 방법은 컨테이너가 범위를 벗어날 때 (함수 종료시) 목록과 그 내용을 자동으로 파괴합니다. 요점은 : C ++는 이와 관련하여 매우 "자바와 유사"할 수 있지만, 고수준 도구를 사용하여 프로그램을 개발하기로 선택한 경우에만 가능합니다.
/*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();
}