CList 를 사용하여 데이터를 List 구조 안에 차근차근 넣다가보면
특정 위치에서 데이터를 찾을때 GetNext 라는 CList 의 멤버 함수를 사용하게 마련이다.
이때, 헷갈리기 쉬운 것이, GetNext 라고 하면 현재 위치의 다음 위치에 있는
데이터를 내 놓으라고 하는 것 같지만
사실은 현재 위치의 데이터를 뱉어낸 다.음.에 그 다음 위치로 넘어간다는 것이다.
따라서, GetNext 로 나온 데이터만 보고 , 아... 여기에다 업데이트 해야지 잇힝~ 하고는
SetAt 을 사용해버리면, 원하는 위치가 아닌, 그 다음 위치에 데이터 업데이트가 되기 때문에
무척이나 조심해야 한다.
이것이 바로 GetNext 의 함정인 것이다!!! (뭔... 명탐정 코난이냐...)

예제를 통해 확인해보자.

일단 CList 를 사용한 list 구조를 만든다. 헤더에...
int 형의 m_iTest 와 CString 형의 m_strTest 라는 두개의 변수를 가지고 있는 List 구조체? 이다.

class CTest
{
public:
 CTest() {}
 CTest(int m_iTest, CString &m_strTest) { CTest::m_iTest = m_iTest; CTest::m_strTest = m_strTest; }
 void operator=(CTest& test) { m_iTest = test.m_iTest; m_strTest = test.m_strTest; }
 int m_iTest;
 CString m_strTest;
};

정의한 CTest 를 사용해야지
cpp 파일에는 다음과 같은 내용이 들어간다.

CList<CTest, CTest&> m_Test;

// 데이터를 추가해보자
// int 형의 숫자들과, CString 형의 문자열이 차근차근 들어간다.
m_Test.AddHead(CTest(1, CString("a")));
m_Test.AddHead(CTest(2, CString("b")));
m_Test.AddHead(CTest(3, CString("c")));

// 맨 처음의 위치를 받아온다.
POSITION pos = m_Test.GetHeadPosition();
int i = 0;

// 데이터 중 2 가 있으면 4로 바꾸고, CString 형의 문자열도 b 를 d 로 바꾼다는 내용.
while(i<m_Test.GetCount())
{
     CTest test = m_Test.GetNext(pos);
     if(test.m_iTest == 2)
     {
          test.m_iTest = 4;
          test.m_strTest = "d";
          m_Test.SetAt(pos, test);
          break;
     }
     i++;
}

자, 여기서 GetNext 함수를 사용했다.
2가 발견되면 4로 바꾸고 문자열도 d 로 바꾼다.
하지만 CTest 의 내부를 보면 다음 처럼 바뀌어 있다.
// AddHead 를 했으므로 마지막에 한 3, c 가 맨 앞에 있게 된다.
3, c
2, b
4, d

처음의 의도는 2, b 가 들어있는 데이터를 4, d 로 바꾸는 것이었는데
2, b 는 멀쩡하고, 1, a 가 4, d 로 바뀌어 버렸다.
앞서 말한대로, GetNext 를 쓰면
현재의 위치에 있는 데이터를 반환한 뒤 다음 위치로 넘어가기 때문.이다.
따라서, m_Test.SetAt(pos, test) 를 한 시점에서 pos 는
2, b 가 아니라 1, a 의 position 인 것이다 !!!

올바르게 2, b 를 바꾸려고 한다면
다음처럼 해야 한다.

while(i<m_Test.GetCount())
{
     CTest test = m_Test.GetAt(pos);
     if(test.m_iTest == 2)
     {
          test.m_iTest = 4;
          test.m_strTest = "d";
          m_Test.SetAt(pos, test);
          break;
     }
     i++;
     test.GetNext(pos);
}

먼저 GetAt 를 이용하여 정확하게 현재 위치의 데이터를 받아 온 후
조건에 맞으면 SetAt 으로 업데이트를 시켜주고 나서
GetNext 로 다음 위치로 넘어가야 한다.

실험 성공.

출처 : http://lafirr.tistory.com/8
Posted by system
l