template 싱글톤클래스로부터 상속받은 클래스안에서 stl map 구

프로그래밍 일반에 관한 포럼입니다.

Moderator: 류광

Locked
oggari
Posts: 4
Joined: 2005-02-23 13:48

template 싱글톤클래스로부터 상속받은 클래스안에서 stl map 구

Post by oggari »

:oops:

템플릿 형태의 싱글톤 클래스으로부터 상속받은 클래스안에서 map을 두었습니다.
그런데 황당하게도 초기에 씬관리자 클래스안에서 씬들을 map에 삽입하려는데 map 자체에 접근이 안됩니다. 상속받지 않았을 때에는 문제가 생기지 않았습니다.
아래 소스를 보시면서(너무 길죠~ ^^a) 설명드리도록 하겠습니다.

싱글톤 클래스는 젬스1권에 나오는 소스대로 구현했구요
template < typename T >
class Singleton
{
public:
Singleton ()
{
assert( !ms_Singleton );
int iOffSet = (int)(T*)1 - (int)(grSingleton<T>*)1;
ms_Singleton = (T*)((int)this + iOffSet);
}
~Singleton ()
{
assert( ms_Singleton );
ms_Singleton = NULL;
}
static T* GetSingletonPtr() {return (ms_Singleton);}
static T& GetSingleton(){return (*ms_Singleton);}

protected:
static T* ms_Singleton;
};
template<typename T> T* Singleton<T>::ms_Singleton = NULL;

아래는 위 클래스로부터 상속받은 클래스입니다.
typedef map< int, Scene* > iSceneMap; // 맵 타입 정의
typedef map< int, Scene* >::value_type iSceneMapVT; // 맵 value타입 정의

class SceneManager : public Singleton <SceneManager>
{
public:
//.....
void AddScene( int iSceneId );
protected:
iSceneMap m_mapSceneContainer;
iSceneMapVT m_vtSceneContainer;
//......
};

장면마다 다른 씬 클래스를 두었습니다.
class SceneLoading : public Scene
class ScenePlay : public Scene
enum SCENE_TYPE
{ SCENE_LOADING = 1, SCENE_PLAY}

씬을 추가하는 부분
void App::Init()
{ //......
SceneManager SceneMgr;
if( &SceneManager::GetSingleton() )
{
SceneManager::GetSingleton().AddScene(SCENE_LOADING);
SceneManager::GetSingleton().AddScene(SCENE_PLAY);
}
}

void SceneManager::AddScene( int iSceneId )
{
Scene* pScene = NULL;
switch( iSceneId )
{
case SCENE_LOADING:
pScene = (Scene*)(new SceneLoading);
break;
case SCENE_PLAY:
pScene = (Scene*)(new ScenePlay);
break;
default:
break;
}
if( m_mapSceneContainer.find( iSceneId )
== m_mapSceneContainer.end() ) //========>A
{
//assert(m_mapSceneContainer.count(iSceneId) == 0 ); //========>A
m_mapSceneContainer.insert( std::make_pair(iSceneId,pScene) ); //========>B
//m_mapSceneContainer.insert(iSceneMapVT( iSceneId, pScene ) );
//m_mapSceneContainer[iSceneId] = pScene;
}
}

아래처럼 씬관리자를 싱글톤으로 생성하지 않았을때에는 'A'나 'B'에서 아무런 문제없이 넘어간다는 것입니다. 싱글톤으로부터 상속받지 않는다는 것을 제외하고 멤버함수나 변수는 모두 같습니다.
void App::Init()
{
m_pSceneMgr = new SceneManager; // 여기서 m_pSceneMgr은 App의 멤버입니다.
m_pSceneMgr->AddScene(SCENE_LOADING);
m_pSceneMgr->AddScene(SCENE_PLAY);
}
class SceneManager
{
public:
//.....
void AddScene( int iSceneId );
protected:
iSceneMap m_mapSceneContainer;
iSceneMapVT m_vtSceneContainer;
//......
};

유독 싱글톤으로 씬 관리자를 구현했을 때 'A'부분에서 문제가 생깁니다. 아예 접근조차 안되네요.
왜그러는지 아시는 분 도움 글 많이 많이 올려주시길 부탁드립니다. ㅠ.ㅠ
Last edited by oggari on 2005-02-24 13:58, edited 10 times in total.
비회원

혹시 오타인가요?

Post by 비회원 »

Code: Select all

class SceneManager : public Singleton <SceneManager> 
{ 
public: 
//..... 
void AddScene( int iSceneId ); 
protected: 
typedef std::map Scene_Map; 
Scene_Map m_mapSceneContainer; 
//...... 
}; 
map의 선언을 보시면
class std::map<typename _Kty,typename _Ty, typename _Pr, typename _Alloc > 입니다.
기본적으로 키와 타입만 정해주고 쓰죠.
키와 타을 정의해주지 않으신거 같습니다. 일부러 빼고 쓰신건지.
아니면 옮기면서 실수이신건지. 그부분을 한번 체크해 보시기 바랍니다.
비회원

Post by 비회원 »

헉~ 죄송합니다. 수정하면서 이 부분을 넣지 않았네요
씬 관리자 클래스 내부를 아래와 같이 수정합니다.
class SceneManager : public Singleton<SceneManager>
{
// ........
protected:
typedef std::map<int, grScene*> Scene_Map;
Scene_Map m_mapSceneContainer;
};
oggari
Posts: 4
Joined: 2005-02-23 13:48

Post by oggari »

수정을 했는데두 수정이 안되네요.
map의 키값은 int 이구요, value는 SCene* 입니다.
Last edited by oggari on 2005-02-23 20:07, edited 1 time in total.
비회원

음 도움은 못드리지만

Post by 비회원 »

map에서 해당 키값에 해당하는 원소를 검색하신다면
find를 쓰시길 권합니다.
mutimap 이 아닌이상 두개이상의 키값은 존재 하지 않으므로
if( _testmap.find("key") != _testmap.end() )
{
삽입등의 처리...
}
가 좋을 듯합니다.
rusad
Posts: 136
Joined: 2003-12-30 17:58

저도 답변은 아니지만;;

Post by rusad »

Code: Select all

map< key, value > xxx
code 섹션 내에 사용하시면 날라가는 일은 없을겁니다.
로망은 나의 힘!
oggari
Posts: 4
Joined: 2005-02-23 13:48

Post by oggari »

우선 싱글톤이 아닌 경우에는 문제가 없었습니다.
키값과 value도 들어가는 것을 확인했구요.
//인용
if( _testmap.find("key") != _testmap.end() )
{
삽입등의 처리...
}
처럼 해도 싱글톤으로 상속 받은 경우에는 접근 불가더군요.
소수처럼 생각하고 다수처럼 말하자
oggari
Posts: 4
Joined: 2005-02-23 13:48

Post by oggari »

헉 이런... 싱글톤 클래스안에서 오프셋 값 구하는 공식이 틀렸었네요.
int iOffSet = (int)(T*)1 - (int)(grSingleton<T>*)1; // (1)
가 아니구
int iOffSet = (int)(T*)1 - (int)(grSingleton<T>*)(T*)1; //(2)
입니다.
ㅠ.ㅠ
해결되었는데 왜 이렇게 창피한지...
소수처럼 생각하고 다수처럼 말하자
Locked