Singleton 사용하시는 개발자분들 몇 %나 되시는지...

회원 전용입니다. 프로그래밍 관련 질문&논의는 금지!

Moderator: 류광

zupet
Posts: 2764
Joined: 2003-05-13 03:34
Location: NCSOFT LE팀

Re: Singleton 사용하시는 개발자분들 몇 %나 되시는지...

Post by zupet »

verena wrote:디자인패턴은 java에서는 100% 효과를 발휘할 수 있으니깐요. 그만큼 c++언어자체가 java보다는 약간 객체지향이 아니다 정도가 되겠습니다.
디자인 패턴 책을 읽어보시면 예제는 모두 SmallTalk 와 C++ 로 나와 있습니다. 책에 자바에 대한 언급이 있었는지 모르겠는데 일단 책에서는 저 두가지 언어를 위주로 예제와 소개가 나와있죠. 요즘에는 자바와 디자인 패턴 관련 서적도 많이 나오고 그쪽에서 많이 사용하지만 그래도 그렇게 적어버리면 디자인 패턴에 대해서 잘 모르는 분들이 혼란스러워 할 것 같네요. 그리고 제가 이 게첫걋?시작한 이유는 싱글톤의 존재 의미에 대한 것이 아니라 실제 게임 코드를 작성하는데 있어서 싱글톤이 전역 변수와 어떻게 다르게 쓰일 것인가? 에 대한 것이 궁금해졌기 때문입니다. 의미가 다르다곤 하지만 우리는 동일하게 쓰고 있다는게 문제의 시작이죠.

게임 코딩을 하는데 있어서 어떤 경우가 싱글톤이 전역변수보다 낫다고 할 수 있을까요?
류광
Posts: 3805
Joined: 2001-07-25 09:00
Location: GPGstudy
Contact:

Post by 류광 »

GPG1권부터 꾸준히 밀어온 단일체라는 용어를 써주시면 고맙겠습니다.. :)

게임은 아니지만, 전역변수로는 불가능하고 단일체로만 가능했던 경험이 하나 있는데요. 전역변수들이 생성되면서 자동으로 특정 관리자에 등록이 되는 형태였고, 따라서 전역변수들이 생성되기 전에 관리자가 존재해야 하는 상황이었습니다. 그 관리자를 단일체로 만들어서 해결을 했습니다. C++의 분리 링크 모형에서 발생하는 문제점, 즉 전역 변수들의 생성 순서를 보장할 수 없다는 한계를 피하기 위한 것이었습니다. 말하자면 완전한 정적 링크와 DLL을 통한 동적 링크 사이의 중간 지점에 해당하는 상황이라고 할 수 있는데, 게임에서도 비슷한 상황이 발생할 수 있지 않을까요?

존재라는 말이 나왔는데, 단일체는 간단히 말하면 "하나만 존재하는" 객체이고, 위의 상황은 하나 보다는 존재에 강조점이 있던 상황이라고 할 수 있습니다.... 즉, (적어도 C++에서,) 언제 어디서 참조하더라도 이미 유효한 객체임을 보장하는 용도로 단일체가 쓰인 것이죠...
Last edited by 류광 on 2005-02-18 17:44, edited 1 time in total.
류광
Posts: 3805
Joined: 2001-07-25 09:00
Location: GPGstudy
Contact:

Re: 전 조금 다른애기지만 GPG 1권의 단일체에 대해서..

Post by 류광 »

jeddli wrote:일반적인 심플한 Singleton 구현에선 단순하게 Singleton::Instance() 등을 호출하면
원하는 객첵을 얻을수 있게( 아직 생성이 안되어 있다면 생성을 해서 리턴해주는 ) 구현이 되는걸로 알고 있습니다. 그런데 GPG1권의 구현을 보면 어디엔가 전역변수를 선언하듯이 실제로 객체를 생성해줘야합니다. 왜 이렇게 해놨는지.. ( 한라인을 어딘가에 더 쳐야한다는게.. )
예.. 다른 글에서도 한 번 언급한 적이 있는데, GPG1권에 나온 것은 실제로 객체를 생성해줘야 한다는 점이나 복잡한 포인터 변환을 사용한다는 점이나 좀 원시적인 형태인 것 같습니다...
myevan
Posts: 1314
Joined: 2003-03-04 10:21
Contact:

Post by myevan »

대화와 글로 예상해보면...

Code: Select all

class StateManager:
	public StateManager& GetSingleton():
		static StateManager s_kSttMgr;
		return s_kSttMgr

	public void SetRenderState(DWORD enum, DWORD value);
nvidia 의 그것(...)

Code: Select all

	STATEMANAGER.SetRenderState(D3DRS_ZENABLE, TRUE)
실제 사용

Code: Select all

#ifdef USE_SINGLETON
	#define STATEMANAGER StateManager::GetSingleton() // 아아 보기싫어 
#elif USE_GLOBAL
	extern StateManager STATEMANAGER // 아아 아름답다
#endif
의문으로 넘어간게 아닌가 심히 추측됨-_-);
빗자루네 http://www.myevan.net >_<b
궁금이
Posts: 237
Joined: 2005-01-19 11:06
Location: ProjectS

Post by 궁금이 »

빗자루님 의견에 추천~ -0-;;
seeper
Posts: 1483
Joined: 2003-06-06 23:19
Contact:

Re: 전 조금 다른애기지만 GPG 1권의 단일체에 대해서..

Post by seeper »

jeddli wrote:그런데 GPG1권의 구현을 보면 어디엔가 전역변수를 선언하듯이 실제로 객체를 생성해줘야합니다. 왜 이렇게 해놨는지.. ( 한라인을 어딘가에 더 쳐야한다는게.. )
이 이유는 텍스쳐매니져 같이 생성, 파괴 시점을 정확히 제어해야하는 단일체라 그렇습니다.
3D 디바이스가 생성된 후에 한 줄을 치라는 의미이겠지요.
Reiot
Posts: 133
Joined: 2003-10-16 12:02
Contact:

Factory & FactoryManager

Post by Reiot »

류광 wrote: 게임은 아니지만, 전역변수로는 불가능하고 단일체로만 가능했던 경험이 하나 있는데요. 전역변수들이 생성되면서 자동으로 특정 관리자에 등록이 되는 형태였고, 따라서 전역변수들이 생성되기 전에 관리자가 존재해야 하는 상황이었습니다. 그 관리자를 단일체로 만들어서 해결을 했습니다. C++의 분리 링크 모형에서 발생하는 문제점, 즉 전역 변수들의 생성 순서를 보장할 수 없다는 한계를 피하기 위한 것이었습니다. 말하자면 완전한 정적 링크와 DLL을 통한 동적 링크 사이의 중간 지점에 해당하는 상황이라고 할 수 있는데, 게임에서도 비슷한 상황이 발생할 수 있지 않을까요?
비슷한 경험이 있었습니다.

게임 서버에서 사용하는 다양한 타입의 메시지들이 각각 클래스로 정의했고, 이를 생성하는 메시지 팩토리와 팩토리를 관리하는 팩토리 매니저가 필요했습니다. 실제로 해당 메시지를 생성하기 위해서는 팩토리 매니저에게 요청하면, 팩토리 매니저 내부의 해시맵에서 팩토리를 찾아서 생성하는 그런 구조였지요. 이때 메시지 팩토리는 전역 변수로, 그리고 팩토리 매니저는 단일체로 구현을 했는데, 메시지 팩토리의 생성자에서 팩토리 매니저에 자기 자신을 등록하는 방식을 사용했습니다.

단, 클래스를 새로 추가할 때마다 어딘가의 AllMsg.h 에 전역 변수를 등록해주는 매크로를 써야 했다는 귀찮음이 있었네요. 결과적으로 보면 팩토리 매니저를 전역 변수로 선언하고, 각 메시지 팩토리를 하나씩 등록해주는 거랑 별 차이가 없어 보이기도 하더군요. 괜히 시간 아낀다고 legacy 코드를 도입했다가 나중에는 더 큰 손해를 봤다는... :(
Last edited by Reiot on 2005-02-18 20:57, edited 1 time in total.
레이옷(Reiot) at http://reiot.com
아샬
Posts: 87
Joined: 2003-12-30 17:09
Location: AHA Studio
Contact:

Re: 제가 생각하기에는..

Post by 아샬 »

einzero wrote:
zupet wrote: extern ConnectionCount gs_ConnCount;
로 바꾸는 것 뿐입니다. 아.. 물론 소스파일 어딘가에 인스턴스도 하나 더 만들어야 합니다. 아마 ConnectionCount 의 내용이 있는 소스 파일에 한줄 더 타이핑을 해야하는 점이 좀 불편하겠네요.
zupet님의 글을 다시 보고 ^^ 또 한가지 말씀드리자면, 소스 파일에 한줄 더 타이핑 해야 되는 경우가 문제가 되어서 singletone을 쓴 경우가 있습니다 ;; ( 바로 어제 짠 소스 코드인데..) meta file로 부터 header file을 generate 하는 util 을 만들었는데, 어쩌다 보니 이놈이 각 meta file별로 unique 하게 전역 object를 하나씩 access 해야 되는 경우가 생기더라구요. 그렇다고 전역 object를 위해서 header file만 만들던 놈을 cpp file까지 같이 만들게 하자니 불편하고 -_-;; 그냥 간단히 마이어스 singletone 방식으로 header 에 선언하게 만들어 놓으니까 간단히 문제가 해결 되더군요!! 혹시 header file만 가지고 instance를 만들어 내는 방식이 singletone 말고 다른 방법으로도 가능한가요? 제가 이쪽 기반지식이 좀 모잘라서, 고수 여려분들의 의견을 듣고 싶습니다.
전역 변수의 경우엔 DOS 시절에 C 쓸 때 쓰던 법이 있긴 했는데...

Code: Select all

#ifdef GLOBAL_DEFINE
    #define GLOBAL
#else
    #define GLOBAL extern
#endif

GLOBAL ConnectionCount gs_ConnCount;
이런 식으로 헤더에서 잡아주고,

Global.cpp 정도 되는 녀석에서 #define GLOBAL_DEFINE 을 먼저 때려주고

헤더를 include 하면 샤샤샥 ㅡㅡ;;;;
삶은.... 달걀.

A: 언제적 개그냐?
B: 오늘.
across9
Posts: 2
Joined: 2005-02-19 00:46
Location: 조이온
Contact:

Singleton같은 경우는 경험상...

Post by across9 »

Singleton같은 경우는 경험상 Facade 패턴의 성질을 뛴 클래스에서만 사용해 주면 그다지

문제가 없다고 봅니다.. 싱글톤의 인스턴스를 찾가위한 오버해드라.. 사실상 현재로선

별의미가 없는것 같습니다. 사소한 부분 하나하나 모두 싱글톤을 남발해서 사용하면 오히려

코드가 개판 오분 직전이 되겠지만 적절히 필요한 부분 ( 외부에서 클래스 인스턴스를 사용한다 던지

반드시 이프로그램에서는 n개 이하의 인스턴스를 생성해야할때 )에서만 사용하시면

오히려 좀더 깔끔하고 정리된 프로그램을 작성하실수 있을꺼라 생각합니다.

무엇보다 패턴을 사용하기전에 당장의 편리함 보다는 해당 패턴의 특징과 적용시기를 파악하고

적재 적소에 사용하는게 멋진 디자인을 할수있는 길이 아닐까 싶습니다.
Jacky
Posts: 59
Joined: 2004-06-01 09:36
Location: 게임공장

Post by Jacky »

책에서 얼핏 본 기억에 싱글톤 패턴을 쓰는 가장 큰 이유중 하나가
전역변수가 생성/소멸 시점이 불명확하여 오는 버그의 위험을 줄이고자함이라고 합니다..

저는 zupet 님의 방식을 선호합니다.
왜냐면 게임은 성능을 최우선으로 하기 때문이고,
생성 시점을 조절할 수 있기 때문이죠. 소멸은 모르겠네요 ..;

하지만 아무래도 가장 큰 문제가 되는 건 상속이 아닐까요?
zupet 님처럼 한다면 상속시에 코드를 다시 고쳐야 할텐데
만약 라이브러리(*.lib)였다면 싱글톤 방식이 더 안전할 것 같은 느낌입니다.

글쓰다가 GPG1권 내용을 다시 참고하니
가장 중요한 차이점은 객체의 생성/소멸 시점을 통제하는 것이네요.

아샬님처럼 저도 쓰고 있습니다. 그렇게 하면 생성 시점이 헤더 인클루드에 따라 조절이 되지요.
zupet
Posts: 2764
Joined: 2003-05-13 03:34
Location: NCSOFT LE팀

상속과 초기화..

Post by zupet »

sykim25 wrote:하지만 아무래도 가장 큰 문제가 되는 건 상속이 아닐까요?
zupet 님처럼 한다면 상속시에 코드를 다시 고쳐야 할텐데
만약 라이브러리(*.lib)였다면 싱글톤 방식이 더 안전할 것 같은 느낌입니다.
글 중간중간에서 언급 했었는데 '현재 사용하는 게임 프로그래밍'이란 전제 조건이 붙었습니다. 라이브러리를 ㅎ파는 것도 아니고 규모가 큰 작업을 하는 것도 아니고 얼굴도 모르는 다른팀에서 문서와 라이브러리를 던져주는 일이 일어나지 않는다는 조건이 포함된다고 생각합니다. 업체에 따라서 정말 독립된 부서로 명세서만 던져주고 일하는 경우가 있을 수 있지만 대다수 프로그래밍을 할때는 다같이 모여있고 문제가 나면 E-mail 나 업무요청서가 아니라 고개를 돌려서 '~~~씨 이거 어떻게 하는거예요?' 라고 물어보는 업무 방식을 취하고 있지 않나요? ^__^
sykim25 wrote:글쓰다가 GPG1권 내용을 다시 참고하니
가장 중요한 차이점은 객체의 생성/소멸 시점을 통제하는 것이네요.
약간 첨언을 하자면 '왜 객체의 시작과 종료가 반드시 생성자/소멸자여야 할까요?' 라는 질문을 덧붙이고 싶습니다. 단일체(싱글톤)을 쓴다면 이러한 이유는 간단히 설명이 됩니다. 사용자가 신경쓰지 않고 초기화가 되어야 하고 소멸시에 간단히 종료가 되어야 겠죠. 그렇지만 제가 앞에서 언급한대로 초기화의 시점과 위치를 특정할 수 있다면(WinMain 같은) 간단히 그 위치에서 초기화나 종료 함수를 호출해 줄 수 있다는 것입니다.

네.. 별로 객체지향적으로 보이지 않습니다. 예전에 저도 생성자의 순서에 따라 문제가 생기는 경우를 경험한 적이 있는데 여러가지 고민 및 고생 끝에 내린 답변은 '내가 왜 WinMain이 호출되기 전에 이 작업을 해줘야 했던거지?' 라는 생각이 들면서 실제 이 엉뚱한 문제는 아주 사소한 것이고 개발 작업과는 전혀 관계없는 것을 큰 문제로 만들어 버렸다는 것입니다.

짜놓고 보면 WinMain 과 같이 '가장 큰 함수'에서 여러가지 초기화 및 정리를 호출해 주는 것은 전체 코드가 더 깔끔해 보입니다. 한곳에 모아서 전체가 초기화 되는걸 볼 수 있으니까요. 단.. include 좀 해줘야 하죠. 긁적.. 어쨌거나 대부분의 게임은 프로그램이 시작할때 무엇을 어떤 순서로 준비해야 할지 확실히 알고 있고 그것을 실행해줄 수 있습니다. 단지 그 방식이 어떤 접근 방식을 쓰고 있느냐는 것이죠. 혹시 이런 코드를 만드신 분이 없는지 궁금하네요.

MyClass::GetInstance()->Init();

제가 얻은 교훈 한가지... 자신의 취향 때문에 문제를 복잡하게 푸는 것은 백해무익이다!!!!

p.s.경우에 따라선 취향 = 멋진 디자인 이란 대체어가 붙기도 합니다.
Last edited by zupet on 2005-02-19 12:53, edited 1 time in total.
ducklmg
Posts: 155
Joined: 2004-11-08 16:46

off-topic입니다만,

Post by ducklmg »

저의 경우에는

생성자, 소멸자에서는 멤버 값들을 NULL등으로 초기화 하는 일들만 하고

실제 준비나 종료는 Initialize(), Cleanup() 같은 함수를 이용합니다....

생성자는 리턴값을 돌려줄 수 없기 때문에 실패했을 경우에 대비할 수가 없더군요.

(어떤책에서 본거 같은데.... 가물가물 ^^;)
난 너를 만나기 위해 이 세상에 태어났어
그러니 내 생활비는 네가 대 주어야만 해
비회원

Post by 비회원 »

sykim25 wrote:글쓰다가 GPG1권 내용을 다시 참고하니
가장 중요한 차이점은 객체의 생성/소멸 시점을 통제하는 것이네요.
GPG1권에 나온 최종적으로 소개한 단일체는 교과서적인 단일체가 아니라
게임에 특화된 단일체로 알고 있습니다.
즉 단일체의 목적이 아니라 단일체를 게임에서 쓸 수 있게 만든 케이스라고 보여집니다.
그리고 클래스를 전역변수로 두고 생성 소멸을 명확히 할 수도 있겠죠. ^^;

저도 단일체를 사용하지 않습니다. (-1표 군요. ^^)
전부터 궁금하던것인데...
단일체를 사용하면 디버깅이 힘들어지던데
이를 감수하면서까지 사용해서 얻어지는 이점이 무엇일까요?
Jacky
Posts: 59
Joined: 2004-06-01 09:36
Location: 게임공장

Post by Jacky »

zupet 님 글 읽어보니 맞는 말씀이네요.

어차피 제가 사용하는 방식은
클래스 정의 헤더에서

extern CTextureManager TextureMgr;
#ifdef __WINMAIN_CPP__
CTextureManager TextureMgr;
#endif

로 마무리를 짓고
윈메인 소스 파일에서 하나씩
헤더를 선언합니다.

지금 테스트 해본 결과,
#include "a.h"
#include "b.h"
#include "c.h"
를 해 놓고
인스턴스가
a, b, c 순으로 생성되도록 하면,
해제는 c, b, a 순으로 해제되도록 되어 있더군요.
소멸자에 메시지박스를 넣어봤습니다.
MS VS .Net 2003 에서 테스트 했습니다.
이렇게 된다면 충분히 게임에서 단일체를 쓰지 않아도 될 것 같네요.
비회원

싱글턴이 좋다고 했던 녀석입니다 ^_^;

Post by 비회원 »

사실 원리적으로 보자면 전역변수와 다를것이 없는것이 Singleton입니다.
게다가 전역변수는 생성은 스레드 세이프지만 싱글턴의 경우는 DCL같은 기법을 써주지 않으면
인스턴스가 두개 생성될수도 있다는 약점이 있지요.

이것은 굳이 싱글턴만의 이야기가 아니라, 디자인 패턴 모든 경우에 해당되는 것으로서
제 생각이긴 합니다만, 패턴의 사용은 성능최적화에 그 목적이 있는것은 아니라는 생각이 듭니다.
물론 잘 짜여진 디자인으로 성능을 최적화하는 것은 가능하겠습니다만, 대부분의 패턴이
[이패턴 쓰면 프로그램이 더 빨라짐]이라는 것은 아닌 것 같습니다.

싱글턴의 경우, 익히 잘 알려진 패턴으로서, 이걸 쓴다면 이 코드를 읽는 누구라도
[이 객체는 글로벌객체다] 라는 것을 알 수 있게 됩니다. [g_] 와 같은 헝가리안과는 또 다른
표현법이지요. 그 외에 많이 씀직한 팩토리라든가, 퍼사드 같은 것도 마찬가지로 패턴이
적용되어 있다는 것을 알게 되는 순간 이 코드의 사용례라든가, 코드의 사용목적, 심지어는
최초개발자가 무슨 개발의도로서 이것을 만들게 되었는지를 이해하는데도 도움을 줍니다.
덧붙여서, 이건 자기가 오래전에 짰던 코드를 다시 볼 때도 해당되겠지요... ^_^;

일단 저의 경우에는 이것이 가장 크구요... 부가적으로는 역시 생성시점의 명시화가 있습니다.
생성순서를 엄격하게 지켜야 하는 몇 개의 글로벌객체가 있다고 할 때, 글로벌객체는
이것이 애매하고, 글로벌객체 포인터라고 하면 new의 순서를 지켜주면 되겠지만 이래서는
멀티스레드 환경에서는 중복생성될 가능성도 존재하고(물론 동기객체를 사용하면 됩니다만)
객체가 유효한 포인터인지 아닌지를 NULL체크와 같은 불안한 방법을 사용할수밖에 없게
되지요. 물론 글로벌객체로 밀어붙였을때 위의 문제는 다 해결법이 있습니다. 하지만 그렇게
해결한다고 해도, 저라면 차라리 DCL걸린 싱글턴을 쓰고 말겠다라는 생각이 들지요. 워낙에
깔끔하잖아요? ^_^; 물론 더 중요한것은 싱글턴과 같은 글로벌객체를 양산하지 않는
프로그램 디자인이겠습니다만.

요즘 프로그램들은 손발이 너무 많이 늘어나서 Massive한 경우가 대부분인데, 이 경우에는
확실히 디자인 최적화가 도움이 되는 것 같습니다. 작업은 역시 Cooperative Works니깐요.

ps.이건 어디까지나 제 생각입니다. 여기 글을 올리면 무서워요 -_-; 꼬투리 잡힐까봐...
zupet
Posts: 2764
Joined: 2003-05-13 03:34
Location: NCSOFT LE팀

Re: 싱글턴이 좋다고 했던 녀석입니다 ^_^;

Post by zupet »

비회원 wrote:사실 원리적으로 보자면 전역변수와 다를것이 없는것이 Singleton입니다.
게다가 전역변수는 생성은 스레드 세이프지만 싱글턴의 경우는 DCL같은 기법을 써주지 않으면
인스턴스가 두개 생성될수도 있다는 약점이 있지요.

...
좋고 나쁜점은 벌써 앞에 많은 분들이 언급해 주신 것 같네요. 제 첫번째 글을 읽어보시면 아시겠지만 단일체의 정의나 그 장점 단점을 다시 조명해보자고 쓴 글이 아니라(저도 그런 식의 게시물을 너무 많이 쓴것 같군요.) 우리가 '좋은게 다 좋은거다' 식의 코딩을 하고 있는게 아닌가 다시 생각해보자는 의미에서 올린 것입니다. 이 글이 올라오기전에 STL과 디자인 패턴이 잡기술이라는 논의가 있었는데 그 글을 읽으면서 어떠한 기술이나 기법이 단지 장점이 많다는 이유 하나로 쓰고 있는게 아닌가 생각해 보자는 뜻에서 시작한 것입니다.

점심을 고르는 것과 같습니다. 무얼 먹던 큰 차이가 없다면 취향에 맞춰서 그때그때의 생각에 따라 움직여도 되지만 그런 방식으로 맛의 대가가 될 수 없듯이 코드 한줄을 짜더라도 그것이 과연 어떠한 이유에서 쓰는지 조금 더 음미해보고 더 나은 방법이 없는지 고민할 수 있는 자세를 찾아봤으면 좋겠습니다. 그래서 몇번이나 '그 장점이 정말 작업에서 도움이 되었습니까?' 라는 질문을 하고 있는 것입니다.

책에서 보거나 우리가 곰곰히 따져봐서 나오는 단어들이 아니라 정말 이것이 이때 최고의 솔루션이었다!!! 이것이 아니면 이렇게 편하게 못했지~ 등의 얘기를 듣고 싶은 것이죠. 그리고 그것이 아니라면 왜 우리가 이전에 사용하던 방식을 그만두고 새 방식을 쓰고 있는걸까?도 생각해 봐야 한다는 것이죠. 다시한번 말하지만 단일체가 나쁘다 좋다를 논하자는 글이 아닙니다. 과연 그 장점이 우리가 생각하는 만큼 도움이 되느냐 안되느냐를 논해보자는 것입니다.

p.s.물론 많은 사람들을 제 취향에 맞는 점심 식사로 초대하려는 성격이 강하긴 합니다. :)

p.s.2.또한 누군가 '이게 정말 맛있다니까!!! 내가 먹어봤더니 잡지에서 말한것 만큼 죽여줬어!!!' 라고 말해주기를 기대하고 있습니다. :wink:
조프
Posts: 115
Joined: 2005-02-21 02:01
Contact:

Re: 제가 생각하기에는..

Post by 조프 »

einzero wrote:
zupet wrote: extern ConnectionCount gs_ConnCount;
로 바꾸는 것 뿐입니다. 아.. 물론 소스파일 어딘가에 인스턴스도 하나 더 만들어야 합니다. 아마 ConnectionCount 의 내용이 있는 소스 파일에 한줄 더 타이핑을 해야하는 점이 좀 불편하겠네요.
zupet님의 글을 다시 보고 ^^ 또 한가지 말씀드리자면, 소스 파일에 한줄 더 타이핑 해야 되는 경우가 문제가 되어서 singletone을 쓴 경우가 있습니다 ;; ( 바로 어제 짠 소스 코드인데..) meta file로 부터 header file을 generate 하는 util 을 만들었는데, 어쩌다 보니 이놈이 각 meta file별로 unique 하게 전역 object를 하나씩 access 해야 되는 경우가 생기더라구요. 그렇다고 전역 object를 위해서 header file만 만들던 놈을 cpp file까지 같이 만들게 하자니 불편하고 -_-;; 그냥 간단히 마이어스 singletone 방식으로 header 에 선언하게 만들어 놓으니까 간단히 문제가 해결 되더군요!! 혹시 header file만 가지고 instance를 만들어 내는 방식이 singletone 말고 다른 방법으로도 가능한가요? 제가 이쪽 기반지식이 좀 모잘라서, 고수 여려분들의 의견을 듣고 싶습니다.
C++ 표준은 아니고, VC++에서라면

Code: Select all

__declspec(selectany) int var;
이렇게 하면 적당히 알아서 var 변수를 한 개 만들어줍니다.

다른 컴파일러에도 비슷한 방법이 있을꺼라고 생각합니다만, 안써봐서;;;
toparada
Posts: 18
Joined: 2002-03-05 09:00

제 생각엔...

Post by toparada »

하나의 인스턴스만 존재해야 하는 경우, 전역변수로 해놓으면 아무래도 실수가 있기 마련입니다. 이 클래스는 꼭 하나만 만들어야 돼. 이 클래스는 꼭 참조할 때 이걸 호출하고 참조를 끊을 때 이걸 호출해야 돼.. 이런식으로 약속이 쌓이다보면, 코드 유지보수가 힘들어지겠죠. 이용하는 사람이 자동적으로 규칙에 맞게 짜도록 만드는 것이 패턴이 아닐까요?
Like a Humming bird..
비회원

참고자료

Post by 비회원 »

"GoF의 디자인 패턴" (피어슨 에듀케이션 코리아, 김정아 역) 책에서 Singleton 부분의 일부를 발췌한 것입니다.
...

어떻게 하면 우리는 클래스의 인스턴스를 하나만 만들고, 이 인스턴스에 쉽게 접근할 수 있을까? 물론 전역 변수를 이용해서 이 객체로 접근하도록 하면 여러 개의 인스턴스를 만들 필요가 없게 된다.

그러나 이보다 더 좋은 방법은 클래스 자체가 자신의 유일한 인스턴스로의 접근 방법을 자체적으로 관리하게 하는 것이다. 이 클래스는 자기 자신 말고는 다른 인스턴스가 생성될 수 없음을 보증할 수 있고, 클래스 자체가 인스턴스에 대한 접근 방법을 제공할 수 있다. 우리는 이를 Singleton 패턴이라고 한다.

...

4. 인스턴스의 개수를 변경하기가 자유롭다. Singleton 클래스의 인스턴스가 하나 이상 존재할 수 있도록 변경해야 하는 경우도 있다. 애플리케이션에 존재하는 인스턴스가 다수여야 하는 경우도 하나가 존재해야 하는 경우와 동일한 방법으로 해결하는 것이다. 즉, Singleton 클래스의 인스턴스에 접근할 수 있는 허용 범위를 결정하는 오퍼레이션만을 변경하면 된다.

...
Post Reply