2012-09-17 3 views
2

나는이 같은, 내가 데이터를 저장 링크 목록 및 다음 노드에 대한 포인터, Node<T>* next있어 :연산자 ++가 링크 된 목록의 다음 노드 포인터로 진행하도록하려면 어떻게해야합니까?

template <class T> 
struct Node 
{ 
    T data; 
    Node<T>* next; 
}; 

것은 나는이에 후행 증가 연산자를 데려 가고 싶다는, 그것 때문에 내 노드의 이전 값을 반환하지만 참조는 증가시킵니다. 내가 할 경우이

Node<int>* someNode = someList.SomeNode(); 
Node<int>* tmp = someNode++; 

tmp 원래 someNode 값이 될 것이나, 그래서 someNodesomeNode->next이 될 것입니다.

구조체에 연산자를 넣을 수 있습니까? 나는 그것을 시도하는 방법을 시도해 보았지만, 나는 사업자를 다루지 않았기 때문에 어떻게해야할지 모른다.

+0

"구조체에 연산자를 넣을 수 있습니까?" 예. C++에서 구조체는 클래스처럼 멤버 함수를 가질 수 있음을 기억하십시오. – drescherjm

+0

구조체는 클래스와 동일하지만 두 가지가 있습니다. 기본 액세스 수정자는 public이며 상속도 기본적으로 public입니다. 다른 것은 완전히 똑같습니다. –

+0

고마워요.하지만 여전히 someNode ++을하는 데 문제가 있습니다. Michael Krelin 회원이 저에게 말했습니다. 그 이유는 someNode가 포인터입니다. Node * no 노드 , someNode ++ MVC는 캐스팅 할 수 없다고 말합니다. – freesoul

답변

5

포인터와 같은 기본 유형에 멤버 함수를 추가 할 수 없습니다.

정의하려는 것은 반복자입니다. 성공하는 노드 포인터를 통해 래퍼 클래스를 사용

template <class T> 
struct NodeIterator 
{ 
    NodeIterator(Node<T>* current) : current(current) {} 
    NodeIterator& operator ++() { current = current->next; return *this; } 
    NodeIterator operator ++(int) { 
     NodeIterator retVal = *this; 
     ++(*this); 
     return retVal; 
    } 
    T* operator->() const { return &current->data; } 
    T& operator *() const { return current->data; } 
    Node<T>* current; 
}; 

은 참조를 std::slist<>implementation를 참조하십시오. template<typename _Tp> struct _List_iterator을보십시오. STL 구현을 읽는 것이 많은 책보다 낫습니다.

사용법 :

NodeIterator<T> it = &node; 
++it; 
T& t = *it; 
+0

덕분에 매우 유용합니다! – freesoul

+0

답변을 수락 할 수 있습니다. 이게 내 대답인지 상관 없어요;) http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work – PiotrNycz

4
Node<T>& operator++(int) {…} 

은 구현하려는 회원입니다.

+0

사실,하지만 내 코드에서 someNode가 포인터인데, 나는 방금 – freesoul

+0

을 편집하고 싶지는 않지만, 노드 * operator ++ (노드 * & p, int)', 믿다. –

+0

'연산자 ++'에 형식 매개 변수가 너무 많습니다. 왜 그렇게해서는 안되는지 궁금합니다. – freesoul

0

코드가 작동하려면, 당신은 당신의 포인터 클래스 operator++을 정의 할 수 있어야합니다 것입니다. 그것은 허용되지 않습니다. 하지만 다른 명명 된 함수를 정의 할 수 있습니다. 예를 들어 :

template <typename Node> 
Node goto_next(Node& node) { 
    Node result = node; 
    node = node->next; 
    return result; 
} 

그런 다음 당신은 다음과 같이 사용할 수 있습니다 :

Node<int>* tmp = goto_next(someNode); 

또 다른 옵션은 실제 반복자 클래스를 제공하는 대신 포인터를 사용하는 :

Node<int>::iterator someNode = someList.begin(); 
Node<int>::iterator tmp = someNode++; 

확인을하여 반복자는 Node<T>* 멤버를 유지하고 반복자 개체의 복사본을 반환하기 전에 내부 포인터를 ++ 연산자로 업데이트하십시오.

0

정말 그렇게하고 싶지 않습니다. 포인터에 ++을 사용한다는 아이디어는 위험한 정도로 일반적인 반복자 패턴에 가깝습니다. 전체 거리로 가서 진정한 반복 클래스를 만들어야합니다. std::list<T>::iterator을 생각해보십시오.

반복자는 다음 노드로 이동 operator ++ 같은 것들을 제공하고, 노드의 데이터에 대한 간단한 액세스를 제공하는 operator -> 과부하 노드 포인터에 재치있는 인터페이스를 제공하는 매우 가볍고 래퍼입니다. 클라이언트 코드를 포인터를 사용하여 반복기를 사용하는 것으로 변환하는 것은 구문이 거의 동일하기 때문에 매우 간단합니다.