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