검색결과 리스트
Programming/이런저런것들에 해당되는 글 14건
- 2010.03.18 싱글턴 싱글턴 싱글턴
- 2009.12.03 PerformanceCounter 와 timeGetTime 과 Assembly count 비교
- 2009.12.03 path 잡아줄때 은(는) 예상되지 않았습니다. 에러날때.
- 2009.10.30 std::map 에서 포인터를 선언된 녀석을 가져오는 법
- 2009.10.12 가변인자를 사용한 매크로 사용법
- 2009.08.20 Parameter 와 argument의 차이점
글
웹서핑 조금만 해도 나오는 싱글턴 패턴 소스.
두번째 테스트로 상속을 받지 않고 싱글턴을 적용해 보았다.
class C : public CLmSingleton2<C> 로 선언 자체가 안된다. 소스를 보면 서로가 서로를 상속 받는 구조가 되어버린다.
평소처럼 사용하다가 싱글턴 클래스 상속과 싱글턴을 상속받은 부모 클래스를 다시 자식 클래스가
상속을 받아서 쓰는부분에 대해 궁금함이 생겼다.
일반적인 싱글턴 소스들
template< class T > class CLmSingleton { public: static T *getInstance() { if( !s_pInstance ) s_pInstance = new T(); return s_pInstance; } static void releaseInstance() { if( s_pInstance ) { delete s_pInstance; s_pInstance = NULL; } } protected: static T *s_pInstance; }; template< class T > T *CLmSingleton< T >::s_pInstance = 0;
//-------------------------------------------------------------- template< class T > class CLmSingleton2 : private T { public: static T* getInstance() { // if use in multi-thread env, should add lock here. static CLmSingleton2<t> s_Instance; return& s_Instance; } protected: CLmSingleton2() {} virtual ~CLmSingleton2() {} }; #define SINGLETON(p) CLmSingleton2<p>::getInstance()
상단에 있는 싱글턴 소스는
class A : public CLmSingleton<A> { public: A() {} virtual ~A() {} int a; }; A testClass; // 일반적인 정적 변수 선언이 가능. testClass.a = 99; // 이것은 단순히 testClass 라는 클래스 멤버변수의 값만 바뀐다. A* pA0 = testClass.getInstance(); // pA0의 멤버변수 a의 값은 쓰레기 값 A* pA1 = A::getInstance(); A* pA2 = CLmSingleton<A>::getInstance(); // pA0, pA1, pA2 세 포인터의 주소는 동일하다. pA2->a = 98; // pA0, pA1, pA2의 멤버변수 a가 전부 갱신됨.
testClass 와 포인터들은 다른 주소를 갖는다. 다만 testClass.getInstance() 로 불러오는 인스턴스만은 동일하다.
각각의 인스턴스는 동일하지만 ( testClass != 포인터 ) 이기 때문에 싱글턴이라 부르기 어렵다.
또한, 싱글턴의 특징 중 하나인 외부로 공개하지 않는 생성자와 소멸자가 public이다.
결국, 저 클래스는 실수로라도 정적 변수로 선언을 하게 된다면 나중에 문제가 커질 가능성이 있다.
혹시나 해서 생성자와 소멸자를 protected 와 private로 했는데, 생성자에 접근을 하지 못해 컴파일 에러가 뜬다.
class B { public: B() {} virtual ~B() {} int b; };
B* pb0 = B::getInstance(); // 상속을 받지 않았으므로 B에는 getInstance()란 메소드가 없어 오류
B* pb1 = CLmSingleton<B>::getInstance(); // B 클래스라는 새로운 인스턴스 생성 성공.
마지막 테스트는 상단 소스중 CLmSingleton2 로 했다.
class C { public: // protected 도 가능 C() {} virtual ~C() {} int c; };
두번째 싱글턴의 경우, 그 특징은 사용하려 명시한 클래스의 자식클래스로 상속이 된다. 첫번째는 싱글턴 자체가 부모클래스이고 사용하고 싶은 클래스는 자식클래스로 상속을 시키는 구조다.
이 싱글턴은 단지 아래 방법만이 가능하다.
C* pc0 = SINGLETON(C);
C* pc1 = SINGLETON(C);
두번째 싱글턴의 경우 클래스 생성자가 public이든 protected든 인스턴스가 생성이 된다. protected인데 생성이 되는 이유는 싱글턴이 부모의 생성/소멸자를 상속을 받았기에 내부에서는 부모를 참조할 수 있기 때문이다. private의 경우 생성/소멸자를 상속 시키지 않아 컴파일 에러가 난다.
//----------
그리고 두 싱글턴의 차이를 보자면 첫번재는 동적 인스턴스이다. 가져올때 없으면 new로 할당을 하고 존재한다면 이미 만들어진 인스턴스를 가져온다. 하지만 소멸자는 불리지 않아 인스턴스가 제대로 지워졌는지 확인이 안된다.
아니면 releaseInstance()를 호출하는 수 밖에 없다.
하지만 두번째 싱글턴은 정적 인스턴스이기 때문에 클래스 자체가 파괴가 되거나 프로그램이 종료가 된다면 메모리를 반환을 한다. 메모리 해제를 할 필요가 없다는 것이다.
그리고 첫번째 싱글턴처럼 인스턴스를 생성할 때 여러 방법이 불가능하다. 싱글턴 생성이나 인스턴스를 가져옴에 있어 통일성이 있다.
만약, 첫번째 싱글턴처럼 이렇게 만드나 저렇게 만드나 똑같은 인스턴스가 나온다면 인스턴스를 가져올 때 통일적이지 않아 나중가면 햇갈릴 가능성이 있는 것이다.
개인적으로 두번째 싱글턴이 좋다.
'Programming > 이런저런것들' 카테고리의 다른 글
유니코드 기반에서 콘솔 출력에 대한 문제. (0) | 2010.10.27 |
---|---|
3차원 배열? 헤딩과 삽질! (0) | 2010.05.25 |
PerformanceCounter 와 timeGetTime 과 Assembly count 비교 (0) | 2009.12.03 |
path 잡아줄때 은(는) 예상되지 않았습니다. 에러날때. (0) | 2009.12.03 |
std::map 에서 포인터를 선언된 녀석을 가져오는 법 (0) | 2009.10.30 |
설정
트랙백
댓글
글
이 프로그램은 Sleep( 2000 )을 걸고! 퍼포먼스 카운터와 어셈블리 카운터와 타임겟타임을 비교해본것임.
순서대로 curTime 은 Performance Counter로 계산한 Elapsed time 이라고 할까요? 단위는 ns
part pc 는 ms단위의 Performance Counter,
curRe 는 앞에는 Performance Counter, 뒤에는 Assembly count 인데, 바로 전 상황과 현재의 차이.
asm pc 는 Assembly counter,
tgt.. timeGetTime
마지막 pc 는 순수한 Performance Counter의 값.
curRe 에서 보이듯이 어셈으로 테스트 했을땐 sleep( 2000 )에 맞게 딱딱 떨어졌는데,
퍼포먼스 카운트는 정확하게 2000으로 떨어지지가 않는다.( 요기도 역시 ns 단위 )
중간에 한번 변위가 엉망인 이유는 듀얼 코어.. 크흑.
확실히 퍼포먼스 카운터가 정밀도가 높아서 2초 단위로 찍어도 ns에서 나온 결과를 보면 수치가 조금씩 다르다.
멋쟁이 정밀도. 대신에 그 만큼 느리다는 단점은 널리 알려진 것이고.
근데.. 온라인 게임에서 쓰기에 ns단위까지 갈 필요가 있을까 라고 개인적으로 생각해본다.
그래서 개인적으로 timeGetTime을 주로 쓰는데 가끔 테스트로 GetTickCount 역시 사용하고. ㅋ
하지만 정밀도는 조금 버리는 한이 있더라도 역시 게임은 반응이 빨라야 재밌지. 함수 호출하는 시간을 조금이라도 더 아껴서
빠른 반응을 보인다면 약간의 딜레이정도는 무난하지 않을까 싶다. 그런의미에서 이제는 어셈 카운터가 원츄~!
참고로. performance counter 와 assembly counter 는 __int64형 timeGetTime은 DWORD형.
참고2. 어셈카운터는 ns 에서 0이 하나 더 붙어있는 값으로 나오더라 ㅋㅋ
'Programming > 이런저런것들' 카테고리의 다른 글
3차원 배열? 헤딩과 삽질! (0) | 2010.05.25 |
---|---|
싱글턴 싱글턴 싱글턴 (0) | 2010.03.18 |
path 잡아줄때 은(는) 예상되지 않았습니다. 에러날때. (0) | 2009.12.03 |
std::map 에서 포인터를 선언된 녀석을 가져오는 법 (0) | 2009.10.30 |
가변인자를 사용한 매크로 사용법 (0) | 2009.10.12 |
설정
트랙백
댓글
글
C:\unigine\externs\bin;C:\unigine\lib;C:\unigine\bin;C:\Python26;"C:\Program Files\Microsoft DirectX SDK (October 2006)\Utilities\Bin\x86";%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;c:\Program Files\Microsoft SQL Server\90\Tools\binn;C:\Program Files\Microsoft SQL Server\90\Tools\binn;C:\Program Files\TortoiseSVN\bin;C:\Program Files\Common Files\Compuware;C:\Program Files\Microsoft SQL Server\90\Tools\binn\;C:\Program Files\Unigine\Evaluation Kit\tools\x86
위에는 실제로 사용하는 나의 path 경로 였었음.
헌데 scons를 쓰려고 하닌까 자꾸만 타이틀의 오류가 나면서 안되길래 한참을 고민했는데,
결국 찾아낸 문제의 부분!! "C:\Program Files\Microsoft DirectX SDK (October 2006)\Utilities\Bin\x86";
dx가 두가지가 깔려있는데 2006 8월이랑 2009 3월버전. 물론 2006 8월은 쓰이질 않고 지우는걸 깜박해서 그냥 냅뒀었는데, 그게 문제가 될줄이야.
요기까지는 잡설이었고.
요점! path 잡을때 ( ) 가 들어가면 링크가 엉망이 됨....
젠장 (October 2006)...
예상되지 않았다는 오류가 난다면 자신의 컴퓨터 path가 제대로 되어있는지 확인을 해보자. 혹시 몰라 검색해보니, path가 안 잡혀 있는 상태로 뭔가를 하려 할때도 난다고 하는데 그 부분은 아직 헤딩해보질 못해서 잘 모르겠다.
내컴터 오른쪽클릭 - 시스템 등록 정보 - 고급 - 환경변수 - 시스템변수 - path에 가면 자신의 윈도우 path를 수정할 수 있다.
글타고 막 수정하진 말자. 언제나 백업을 위주로~!
포스팅 할 예정이 아니어서 인증샷찍는걸 깜박..;
'Programming > 이런저런것들' 카테고리의 다른 글
싱글턴 싱글턴 싱글턴 (0) | 2010.03.18 |
---|---|
PerformanceCounter 와 timeGetTime 과 Assembly count 비교 (0) | 2009.12.03 |
std::map 에서 포인터를 선언된 녀석을 가져오는 법 (0) | 2009.10.30 |
가변인자를 사용한 매크로 사용법 (0) | 2009.10.12 |
Parameter 와 argument의 차이점 (0) | 2009.08.20 |
설정
트랙백
댓글
글
std::map< int, int > Map1;
이런녀석이 있다고 할때 Map1[1], Map1[2] 처럼 접근이 가능하다. 물론 리턴값은 first에 맞는 second
그런데 std::map< int, int > *pMap2;
이렇게 선언되어있는 녀석이 있다면 pMap2[1], pMap2[2] 의 접근이 불가능하다.
이유인 즉슨!!
일반 map 에서 정의되어 있는 [] 오퍼레이터가 제대로 작동하지 않아서이다.
포인터 map에서의 []는 int *pI = new int[10]; 에서의 pI[1] 와 같은 의미.
결국 map 이라는 녀석이 할당된 메모리 주소를 쭉 찾아가다보니 당연히 first 값을 넣어도 second가 나오지 않는다.
( 확실한건 아니고 나의 가설일뿐 ㅎㅎ )
그렇다면 포인터로 선언한 map은 쓸수 없는가?
당연히 사용이 가능하다. 세가지 방법중 맘에 드는걸로 쓰는걸 추천~
1. 레퍼런스를 만들어 참조한다.
std::map< int, int > &refMap = *pMap2;
- 장점은 일반 map 사용하듯이 쓰면 된다.
- 단점은 주소 복사연산이기 때문에 변수 생성시에만 가능하다.
std::map< int, int > &refMap; << 선언 에러
std::map< int, int > refMap;
&refMap = *pMap2; << 말도 안되는 연산. 당연히 에러
2. 주소를 열심히 찾아가는 방법을 쓴다.
int iSecond = (*pMap2)[0];
- 장점은 레퍼런스가 아니니 때문에 어디서든 map 포인터에서 second의 값을 불러올 수 있다.
- 단점은 아직 못 찾았는데, 개인적으로 미관상 소스가 이쁘지 않다! ㅋㅋㅋ
3. 이터레이터를 사용한다면 아무 문제없다.
포인터든 아니든 이터레이터는 진리.
post script.
map은 [] 오퍼레이터 내부에서 find 와 insert를 돌린다. find로 있으면 second리턴 없으면 insert
( 이걸 모른다면 map 공부를 다시 하시길.. ㅋ )
위에 쓴 예시는 내부에 값이 있다는 전제하에 쓴 글임니당.
이런녀석이 있다고 할때 Map1[1], Map1[2] 처럼 접근이 가능하다. 물론 리턴값은 first에 맞는 second
그런데 std::map< int, int > *pMap2;
이렇게 선언되어있는 녀석이 있다면 pMap2[1], pMap2[2] 의 접근이 불가능하다.
이유인 즉슨!!
일반 map 에서 정의되어 있는 [] 오퍼레이터가 제대로 작동하지 않아서이다.
포인터 map에서의 []는 int *pI = new int[10]; 에서의 pI[1] 와 같은 의미.
결국 map 이라는 녀석이 할당된 메모리 주소를 쭉 찾아가다보니 당연히 first 값을 넣어도 second가 나오지 않는다.
( 확실한건 아니고 나의 가설일뿐 ㅎㅎ )
그렇다면 포인터로 선언한 map은 쓸수 없는가?
당연히 사용이 가능하다. 세가지 방법중 맘에 드는걸로 쓰는걸 추천~
1. 레퍼런스를 만들어 참조한다.
std::map< int, int > &refMap = *pMap2;
- 장점은 일반 map 사용하듯이 쓰면 된다.
- 단점은 주소 복사연산이기 때문에 변수 생성시에만 가능하다.
std::map< int, int > &refMap; << 선언 에러
std::map< int, int > refMap;
&refMap = *pMap2; << 말도 안되는 연산. 당연히 에러
2. 주소를 열심히 찾아가는 방법을 쓴다.
int iSecond = (*pMap2)[0];
- 장점은 레퍼런스가 아니니 때문에 어디서든 map 포인터에서 second의 값을 불러올 수 있다.
- 단점은 아직 못 찾았는데, 개인적으로 미관상 소스가 이쁘지 않다! ㅋㅋㅋ
3. 이터레이터를 사용한다면 아무 문제없다.
포인터든 아니든 이터레이터는 진리.
map은 [] 오퍼레이터 내부에서 find 와 insert를 돌린다. find로 있으면 second리턴 없으면 insert
( 이걸 모른다면 map 공부를 다시 하시길.. ㅋ )
vector나 list에서도 같은 문제가 발생하겠죵? 테스트를 안해봐서 이건 모릅니다! ㅋ
'Programming > 이런저런것들' 카테고리의 다른 글
PerformanceCounter 와 timeGetTime 과 Assembly count 비교 (0) | 2009.12.03 |
---|---|
path 잡아줄때 은(는) 예상되지 않았습니다. 에러날때. (0) | 2009.12.03 |
가변인자를 사용한 매크로 사용법 (0) | 2009.10.12 |
Parameter 와 argument의 차이점 (0) | 2009.08.20 |
재미없는 if문 (0) | 2009.08.05 |
설정
트랙백
댓글
글
#ifdef WIN32
#define TRACE(fmt, ... ) Func( fmt, __VA_ARGS__ )
#else
#define TRACE(fmt, args...) Func( fmt, ##args )
#endif
'Programming > 이런저런것들' 카테고리의 다른 글
path 잡아줄때 은(는) 예상되지 않았습니다. 에러날때. (0) | 2009.12.03 |
---|---|
std::map 에서 포인터를 선언된 녀석을 가져오는 법 (0) | 2009.10.30 |
Parameter 와 argument의 차이점 (0) | 2009.08.20 |
재미없는 if문 (0) | 2009.08.05 |
매크로 기술 한개 추가! (0) | 2009.07.19 |
설정
트랙백
댓글
글
파라메터(parameter) : 파라메터는 함수에서 정의한 인자를 의미한다.
예 >
void swap( int a, int b ); // 여기서 a, b는 파라메터 이다.
아규먼트(argument) : 아규먼트는 함수에 넘겨줄 변수나 값을 의미한다.
예 >
int x, y;
x = 10;
y = 20;
swap( x, y ); // 여기서 x, y는 아규먼트가 된다.
'Programming > 이런저런것들' 카테고리의 다른 글
path 잡아줄때 은(는) 예상되지 않았습니다. 에러날때. (0) | 2009.12.03 |
---|---|
std::map 에서 포인터를 선언된 녀석을 가져오는 법 (0) | 2009.10.30 |
가변인자를 사용한 매크로 사용법 (0) | 2009.10.12 |
재미없는 if문 (0) | 2009.08.05 |
매크로 기술 한개 추가! (0) | 2009.07.19 |
RECENT COMMENT