C++에서 C#처럼 enum을 쓰는 방법이 있다!

namespace 관련해서 자료를 조사하다가 나온건데...
(참고: C++ namespace(네임스페이스) 코딩 스타일)
 
 

Unreal쪽 자료를 찾아보다가 여길 보니 enum을 C#스타일로 쓰기 위해 namespace를 사용한다는 내용이 나온다. 나도 예전에 생각해봤던건데 진짜로 쓰는 데가 있었구나!

http://udn.epicgames.com/Three/CodingStandard.html


기존의 C++ enum은 다음과 같은 문제가 있었다.
enum Color
{
    Red,
    Green,
    Blue,
... } void Foo(Color color) { switch(color) { case Red: ... break; case Green: ... break; case Blue: ... break; } }

enum이 전역 공간을 돌아다닐 수 있기 때문에 이름 충돌이 일어날 가능성도 높고 - 예를 들면 어디선가 const string Red = "Red"; 같은거 선언하면 모호해진다 - enum보다는 마치 #define된 상수처럼 보이며, 같은 enum소속인지도 알아보기 힘들고, 같은 enum내에 다른 멤버들이 어떤 것이 있는지 알아보기 힘들며, 어디서 사용되는지 유추할 길이 없는 등의 단점이 있다.

약간의 꼼수로는 Color_Red, Color_Green과 같은 이름을 사용하는 방법이 있긴 하다. 나도 지금까지 이렇게 해왔지만 이제 바꿀 예정!


Scoped enum을 사용하는 방법은 다음과 같다.
 
namespace Color
{
    enum Type
    {
        Red,
        Green,
        Blue,
... } } void Foo(Color::Type color) { switch(color) { case Color::Red: ... break; case Color::Green: ... break; case Color::Blue: ... break; } }
이제 각 enum형 상수들이 소속을 가지게 되었다! Visual Studio같은 IDE를 사용한다면 F12등을 누른다거나 Ctrl+Space를 눌러서 Color의 다른 멤버 목록까지 볼 수 있다.

 
다른 방법 - 밑줄 쓰기

다만 변수를 만들 때 ::Type 이라는 것을 붙여 줘야 하는데 - Color::Type 처럼 - 이것도 싫다면 Color_Red, Color_Green 등올 하는 것이 나을 것으로 보인다.

또 밑줄을 사용할 경우, 단독으로 숫자를 사용할 수 있는 장점이 있다. 예를 들면 Keys_1, Keys_2 처럼 사용하는 것도 가능한데, 만약 namespace를 사용한다면 Keys::1, Keys::2 와 같은 방법은 1과 2처럼 숫자로 시작하는 식별자는 컴파일되지 않는다는 면에서 상대적으로 장점으로 볼 수 있다. 뭐 나같은 경우 Keys::D1, Keys::D2로 쓰고 있기는 하다.


 
반응형

중첩된 namespace는 어떻게 써야 하나?

오늘 코딩을 하다가 namespace를 중첩해서 만들어야 할 일이 생겼다. 내가 C#에 영향을 많이 받은지라, 각 namespace의 계층 구조를 만들어서 써보자는 생각을 했다.

그런데 문제가 생겼다. 이거 들여쓰기를 어떻게 해야 할 지 고민된다.

몇 가지 방법을 생각해냈다.

1번

namespace Foo { namespace Bar {
    class ImYourFather
    {
        ...
    }
} }
2번

namespace Foo
{
    namespace Bar
    {
        class INeedACupOfCoffee
        {
            ...
        }
    }
}

3번

namespace Foo
{
namespace Bar
{
class WatchWhereYouShooting
{
    ...
}
}
}



일단 namespace를 제시하는 방법과, namespace와 class의 들여쓰기 방법이 차이가 난다. 따라서 내가 여기에 제시한 것 말고도 여러 변형이 나올 수 있다만, 일단 저 세 개를 후보로 정했다.

1번은 namespace를 옆으로 나열한 것이다. packed 방식이라고 하더라. 들여쓰기는 한 번만 된다.
2번은 namespace마다 들여쓰기를 한 것이다.
3번은 namespace와 class 모두 들여쓰기를 하지 않은 것이다.

예상되는 장점과 단점을 생각해 보자면...

1번
장점
namespace의 계층 구조를 쉽게 파악할 수 있다. 들여쓰기는 한 번만 된다. Visual Studio의 자동 들여쓰기에 의존해도 되므로 편하다. C++은 C#과 달리 namespace를 namespace Foo::Bar {...} 로 선언할 수 없는 것을 가장 유사하게 극복하는 방법이다.

단점
내가 따르는 일반적인 C++ Coding Style을 위반한다. 보통 중괄호는 별개의 라인에 작성해야 한다.




2번
장점
Visual Studio가 알아서 들여쓰기를 해주므로 편하다.

단점
namespace 계층 구조가 깊어질 수록 들여쓰기가 많아진다.




3번
장점
namespace 때문에 들여쓰기가 중첩되는 현상이 없다. 즉, 수평 공간을 낭비하지 않는다.

단점
Visual Studio의 자동 들여쓰기 기능이 있기 때문에 수동으로 왼쪽에 정렬해줘야 하는 불편함이 따른다. 별 것 아니지만 귀찮다.
왠지 namespace만 들여쓰기를 하지 않는게 거슬린다.
계층 구조를 파악하기가 조금 힘들수도 있다.




아... 정말 고민된다!

다른 프로젝트들은 어떻게 하고 있을까?

내가 좋아하는 C#

C#쪽은 대체로 2번 규칙을 따르는 것으로 보인다. 근데 C#은 namespace 지정을 namespace Foo.Bar {...} 이렇게 할 수 있어서 나름 들여쓰기가 절약이 된다.


Google

Google의 경우 3번 규칙과 비슷하다. 다만 중괄호가 같은 라인에 있다.
http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Namespaces


Ogre3D

게임 쪽은 어떨까... Ogre3D를 봅시다.
Ogre3D의 경우 2번 규칙과 비슷하다. 중괄호가 namespace와 같은 라인에 있는 경우가 일반적으로 보인다. 별개의 라인에 중괄호가 위치하는 경우도 있기는 하지만 같은 라인에 위치하는 것이 보다 일반적으로 보인다. 좀 더 살펴본 결과 3번 스타일도 사용하는 것으로 확인되었다. 오픈 스스기 때문에 여러 사람이 작업해서 그런건지 스타일도 여러개다.

Ogre3D의 namespace는 계층이 최대 2단계까지만 중첩되기 때문에 어차피 들여쓰기 문제는 없는 것으로 보인다.


WebKit, Mozilla

외국쪽 사정도 비슷한듯... 들여쓰기에 대한 논쟁이 좀 있다.
http://bugreports.qt.nokia.com/browse/QTCREATORBUG-567

살펴보니 WebKit도 3번 규칙을 따른다. http://www.webkit.org/coding/coding-style.html
Mozilla도 3번 규칙을 따른다. https://developer.mozilla.org/En/Mozilla_Coding_Style_Guide


 VS2010에서 namespace indention 안하는 방법
http://stackoverflow.com/questions/3727862/is-there-any-way-to-make-visual-studio-stop-indenting-namespaces


Unreal Engine

사족: C++에서 C#처럼 enum 쓰기
Unreal쪽 자료를 찾아보다가 여길 보니 enum을 C#스타일로 쓰기 위해 namespace를 사용한다는 내용이 나온다. 나도 예전에 생각해봤던건데 진짜로 쓰는 데가 있었구나!

http://udn.epicgames.com/Three/CodingStandard.html


결론

이것 때문에 몇 시간을 다른 사람들은 어떻게 하고 있는지 찾는데 보냈다. 코딩은 언제 하나 ㅠㅠ

대개 3번 유형을 선택하고 있는 것으로 보이고 간혹 2번, 그리고 드물게 1번 스타일을 사용하는 것으로 보인다.

일단은 1번 스타일로 하려고 한다. 중첩된 namespace를 사용하기에는 가장 편리하고 적합한 것으로 보인다. 그리고 namespace 선언으로 발생하는 탭 하나 정도는 괜찮다. 어차피 C#도 보니까 그러더만... 너무 들여쓰기 많아져서 스트레스 받기도 싫고, 들여쓰기 집어넣느라 스트레스 받기 싫다.




반응형


ONE MUST FALL
 
초딩 시절 죽어라 했던 게임.
 
 
동생이 기억나게 해주었다.
 
그때 들었던 배경음악 아직도 선하다.
 
 
지금 보니, '누군가 하나는 떨어져야 한다'는
 
조금은 가슴아픈 현실의 제목이다.
 
 
1994년 당시 개발사였던 Epic MegaGames는 현재 국내, 국외의 많은 게임 개발사들이 수억원, 수십억원씩을 주고 구입하여, 혹은 로열티를 지불하여 사용하게 되는 Unreal Engine 시리즈를 만든 Epic Games가 되었다.



OMF 2097 배경음악 듣기: http://blog.naver.com/exacall/140061810197


반응형

'일기' 카테고리의 다른 글

레거시 코드와 씨름 중  (0) 2010.10.10
프로그래밍 심리학  (0) 2010.09.15
으아앙대  (0) 2010.02.26
Misirlou 연습중  (0) 2010.02.17
이틀째  (0) 2010.02.16

+ Recent posts