2012-09-14 5 views
2

더 구체적으로 말하자면, 우리가 전형적인 링크 된 목록 구현에서 포인터를 사용하는 이유가 궁금합니다. 노드의 다음 구현으로 인해 발생할 수있는 문제가 있습니까?참조가 포인터를 대체 할 수 있습니까?

template <typename T> 
class Node { 
    T data; 
    Node<T>& next; 
    Node<T>& prev; 
}; 

참조 대신 여기에 포인터를 사용해야하는 이유가 있습니까?

+0

다음 또는 이전 노드가 아닌 경우는 어떻게합니까? – chris

+1

이 목록 구현은 내 튜링 기계에서 잘 작동합니다. – ssube

+0

참조는 null 일 수 없으므로 유효하지 않거나 존재하지 않는 '다음'및/또는 '이전'을 나타내는 방법이 필요합니다. – Joe

답변

4

참조를 설정 한 후에는 참조를 설정할 수 없으므로 변경 불가능한 연결 목록 구현이 다소 까다로울 수 있습니다. 참조를 변경하려는 경우 다시 작성할 수있는 객체에 참조를 래핑해야합니다.

참조에 NULL 값을 설정하는 방법도 없으므로 목록의 끝을 나타내는 데 약간의 상상력이 필요합니다.

링크 된 목록의 포인터를 사용하는 것이 더 좋으며, 더 좋게는 std::list<>을 사용하는 것이 좋습니다.

+0

포인터가 작동하는 법을 배우려하지 않는 한, 더 좋은 방법은 링크 된 목록을 사용하지 않는 것입니다. –

1

왼쪽 값 참조는 포인터를 대체 할 수 없습니다. 그들은 다른 일을합니다.

lvalue 참조는 lvalue로 초기화해야하며 lvalue 참조는 나머지 기간 동안 해당 객체를 참조합니다. 리바운드 수 없습니다. 이것은 목록 노드에 대한 두 가지 즉각적인 문제점을 제시합니다.

목록을 어떻게 시작합니까? "이전"이없는 노드를 만들고 싶다면 prev 구성원을 Node 개체로 초기화해야합니다. Nodeprev이 목록의 머리 부분을 나타 내기 위해 자체라고 생각할 수도 있지만, 이는 좌변 값 참조의 잘못된 선택을 피하기 위해 작동합니다. (예 : Node<T> emptylist = { T(), emptylist, emptylist }; //eurgh)

둘째, 어떻게 목록을 조작하나요? nextprev의 바인딩을 변경할 수 없으므로 목록을 변경하는 유일한 방법은 완전히 새로운 노드 집합을 구성하고 모든 단일 data 요소를 복사하는 것입니다.

+1

"lvalue로 참조를 초기화해야합니다"- 글쎄 ... 실제로는 아닙니다. 'int const & cr = 5; int && rv = 5;' – Xeo

관련 문제