Game Dev/Article

중첩을 피하는 코딩 스타일

AKer 2009. 4. 12. 02:08
반응형
코딩을 하다보면 계층 구조 깊숙이 있는 포인터를 다루는 경우가 많이 있다. 예를들어 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