임시 블로그 이름

이런 코드는 짜지 말자. 본문

이것 저것

이런 코드는 짜지 말자.

paeton 2013. 2. 27. 23:17
이런 코드는 진짜 짜지 말자

나는 코드를 잘 짜는 방법은 잘 모르겠다. 여기저기 검색 해 보면 좋은 조언들이 많이 나온다.


그 대신에 나는 정말 이런식으로 짜면 안되는 케이스들을 보여주고 싶다.

혼자서 공부하는 코드라면 모르겠지만, 회사에서 직장에서 코딩을 업으로 하면서, 아래 소개된 식으로 코드를 짜는건 정말 여러사람에게 민폐를 끼치는 행동이다.

C++기준으로 써본다.



1. 이미 있는 타입에 대한 재정의에.... 대한 재정의...

무슨 말이냐, 예를 들면 아래 코드 같이 짠거 말이다.


typedef int TData;


...


typedef TData DataPoint;


...


DataPoint x = 0;


이건 정말 typedef를 남발한 코드다.

지금이야 한번에 저 세 줄을 같이 볼 수 있으니 상관 없지만, 만약 저 세줄이 서로 다른 헤더파일과 소스파일에 있다면????


물론 typedef를 써야 할 경우가 있다. 하지만 이런식은 절대 안된다.

왜 안되냐고 물어본다면 저런식으로 짜여진 코드를 디버그 해보면 안다.


x에 무슨 값이 들어오는지, x에 무슨 값이 들어와야 하는지 알기 전에, x가 무슨 타입인지 알아야 되는데, 저런식으로 정의된 코드는 일단 x가 무슨 타입인지 한참 찾아봐야 알 수 있다. 한참을 찾아갔더니 int형이라니.... 읽는 사람에게 고통을 안겨주는 코드다.


필요한게 int형이면, 그냥 int로 쓰고, 뭔가 의미를 부여하고 싶다면 변수이름으로 해결하자.




2. 잘못된 클래스 설계

첫째, C++을 사용한다는 것은 OOP를 사용한다는 거다. OOP를 쓰는 이유를 제대로 이해 했다면, 클래스 외부에 알려줘야 할 필요가 있는 변수/함수를 제외하고는 모두 private으로 선언하는게 맞다는걸 알고 있을거다. C++ 클래스를 설계해놓고 모든 변수/함수를 public으로 해놓는 것은 하지 말자.


둘째로, private변수를 만들었다면, 그 변수의 포인터나 주소를 외부에 주는것은 하지 마라.

다음 코드를 보자.


Class CMyClass

{

public:

CMyClass();

~CMyClass();


int *GetSize()

{

return &m_Size;

}


private:

int m_Size;


}


GetSize()라는 함수가 멤버변수의 주소값을 넘겨주게 되어있다. 이럴거라면 m_Size를 private변수로 만들 필요가 없다. 이런 코드는 오류의 주범이 된다. 멤버 변수는 멤버 함수에 의해서 제어되는것이 좋다. 그렇지 않으면 언제 어디서 저 값을 변화시키는지 알 수 없게 된다. 이건 즉, 버그가 발생했을 때 언제 어디부터 찾아봐야하는지 모르게 된다는 뜻이다.


클래스 내부 함수에서 m_Size 변수를 이용해서 여러가지 연산을 하는데, 만약에 저 m_Size라는 변수를 외부에서 잘못 건드려서 원래 가져야 할 범위를 벗어난다면? 클래스는, OOP는 이러라고 만들어놓은게 아니다.




셋째, 클래스 내부의 메모리 할당/해제 함수를 외부에서 마음대로 동작하게 하는 설계

다음 코드를 보자.

Class CMyClass

{

public:

CMyClass()

{

MemoryAlloc();

}


~CMyClass()

{

MemoryFree();

}



void MemoryAlloc(void)

{

MemoryFree();


m_pMemory = new int[10];

}


void MemoryFree(void)

{

if( m_pMemory != NULL )

{

delete[] m_pMemory;

m_pMemory = NULL;

}

}


private:


int *m_pMemory;


}


여기서 문제는 MemoryAlloc()과 MemoryFree()가 public이라는 것이다. 외부에서 클래스 내부의 메모리를 마음대로 없애고 할당할 수 있다. 위의 클래스는 하는 일 없이 메모리 할당과 해제만 하고 있지만, 다른 코드가 중간에 들어갔을 때, 이런식으로 외부에서 메모리 할당을 마음대로 콘트롤 한다는 것은 매우 위험하다. 위의 코드 같은 경우 반드시 MemoryAlloc()과 MemoryFree()를 private으로 감추어야 한다.



3. C와 C++을 무분별하게 섞어쓰는 경우

분명히 어떤 함수가 특정한 클래스 안에서만 불린다면, 그 클래스의 멤버 함수로 선언하는게 맞다.

그게 아니라면, 비슷한 일을 하는 함수들을 하나 만들어서 따로 클래스를 하나 만들던지.



4. GOTO

이글을 쓰면서도 분노를 금할 수가 없다. 무려 C++이라는 언어 안에서 GOTO라는 글자를 봤을때, 내 눈이 잘못된줄 알았다.

그냥 쓰지 마라. 그냥, 제발. 왜 쓰지말라고 하는지는 검색이라도 좀 해보자.



5. Include의 남발

하나의 클래스는 의미상으로, 그 클래스를 구성하는 하나의 헤더파일(*.h)과 소스파일(*.cpp)파일로 존재 해야 한다. 즉, 기본적으로, 시스템이나, C++기본 라이브러리를 제외하고는 그 클래스의 파일만으로 컴파일되고 실행될 수 있어야 한다. 즉, 다른 클래스나 파일들에 의존성이 낮아야 한다는 것이다.


문제는, 여기저기 타입들과 함수들을 정의해놓고, 그것들을 include 해야만 클래스가 동작하게 만든다거나, 다른 클래스들의 파일들이, 상속관계도 아니면서 현재 만들어놓은 클래스의 참조해야만 동작하게 만들어 놓는다던가 하는 일이다.


include에 의해서 서로 여기저기 얽혀 있는 코드들은 다시 사용할 수 가 없다.






위의 사례와, 설명할 수 없는 다른 오류들이 모두 들어있는 코드를 디버깅하느라 야근을 해야 하는 이 상황이 빡쳐서 쓴다.....

저 코드를 짜신분이 코드를 저따위로 짜놓고, 대기업에서 개발관련 차장을 맏고 있다는게 어이가 없을 뿐이다...



끝.

'이것 저것' 카테고리의 다른 글

미국에서 차 사기 - 2  (1) 2020.02.19
미국에서 차 사기 - 1  (1) 2020.02.17
맥북 Ethernet Adapter 문제....  (0) 2012.01.08
프로젝트의 계절인가보다...  (0) 2011.12.01
Matlab에서 gmail 서버 이용 메일 보내기  (0) 2010.11.10
Comments