반응형
코딩을 하다보면 계층 구조 깊숙이 있는 포인터를 다루는 경우가 많이 있다. 예를들어 A 포인터에서 B 포인터를 얻어내고 B 포인터에서 C 포인터를 얻어내고... 이 경우 포인터를 얻어내는 것도 쉬운 일이 아니지만, 잘못된 포인터를 참조하지 않도록 방어적 프로그래밍을 하는 것도 매우 중요하다. 그리고 대부분의 경우 NULL 체크를 위해 다음 2가지 중 한 방법을 취할 것으로 생각된다.
A* pA = NULL; B* pB = NULL; C* pC = NULL; pA = GetA(); if (pA) { pB = pA->GetB(); if (pB) { pC = pB->GetC(); if (pC) { pC->Func(); } } // end of if (pB) } // end of if (pA)1. if 문의 중첩
A* pA = NULL; B* pB = NULL; C* pC = NULL; pA = GetA(); if (!pA) return; pB = pA->GetB(); if (!pB) return; pC = pB->GetC(); if (!pC) return; pC->Func();2. 선행 return
이 2 가지 스타일은 무난하지만 중첩이 많아져서 프로그램의 흐름을 놓치거나, 응집성이 떨어질 우려가 있다. 원하는 작업인 pC->Func()를 호출하기 위해 방어적 작업으로만 10~20줄이 추가되는 것이다. 물론 매크로를 통해서 이러한 체크를 조금 더 짧게 할 수는 있겠지만, return 값의 유무에 따라서 매크로 형태가 달라지고 디버깅이 어렵다는 단점이 있다.
#define CHECK_PTR(a) if (!a) return;3. 매크로 사용
그래서 ? (물음표) 연산자를 사용하여 다음과 같은 스타일을 적용하여 보았다. 이 경우 매크로와 달리 디버깅도 쉬우며, 중첩이 많아지거나 응집성이 떨어질 걱정도 없다. 코드를 분석할 때 약간의 오버헤드가 있긴 하겠지만 중첩문에 비하면 크게 어렵지 않고 익숙해진다면 나름 괜찮은 방법인 것 같다.
A* pA = GetA(); B* pB = pA ? pA->GetB() : NULL; C* pC = pC ? pB->GetC() : NULL; if (!pC) return; pC->Func;4. ? 연산자 사용
반응형
'Game Dev > Article' 카테고리의 다른 글
Minimize All Windows (0) | 2009.04.30 |
---|---|
간단한 ActiveX 수동설치 만들기 (2) | 2009.04.28 |
편리한 STL Container Macro (0) | 2009.03.26 |
Internet File Download (0) | 2009.02.20 |