싱글톤 패턴
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
#include<stdio.h> #include<assert.h> #include "vector" #define AfxGetApp() KSingleton<CWinApp>::GetSingleton() #define DEBUG template<typename T> class KSingleton { private: static T* ms_pSingleton; public: KSingleton() { assert(NULL == KSingleton<T>::ms_pSingleton); KSingleton<T>::ms_pSingleton = (T*)this; } ~KSingleton() { KSingleton<T>::ms_pSingleton =NULL; } static T* GetSingleton() { return ms_pSingleton; } }; /*static*/ template<typename T> T* KSingleton<T>::ms_pSingleton = NULL; class CWinApp : public KSingleton<CWinApp> { public: void Print() { printf("hello\n"); } }; CWinApp theApp; void main() { //KSingleton<CWinApp>::GetSingleton()->Print(); //위에서 메크로 적용 AfxGetApp()->Print(); #ifdef DEBUG //cmd char e; scanf("%c",&e); #endif } |
이벤트 패턴
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
#include <iostream> #include <conio.h> #include <Windows.h> #define KEY_ESC 27 using std::cout; using std::endl; class CAccount { public: struct StateMap { int input; void (CAccount::*f)(); }; static StateMap map[]; enum { STATE_IDLE, STATE_INPUT, STATE_WAIT_ACK, STATE_MAX }; public: int m_iState; CAccount(); void OnIdle(); void OnInput(); void OnWaitAck(); }; CAccount::CAccount() { m_iState = STATE_IDLE; } void CAccount::OnIdle() { cout<< "OnIdle()"<<endl; } void CAccount::OnInput() { cout<<"OnInput()"<<endl; } void CAccount::OnWaitAck() { cout<<"OnWaitAck"<<endl; } /*static*/ CAccount::StateMap CAccount::map[]={ '1',&CAccount::OnIdle, '2',&CAccount::OnInput, '3',&CAccount::OnWaitAck, 0,NULL //sentinel }; void main() { int ch=0; int i; CAccount account; while(ch!=KEY_ESC) { ch =getch(); i=0; while(CAccount::map[i].input!=0) { if(ch == CAccount::map[i].input) { (account.*(CAccount::map[i].f))(); } ++i; } } } |
스테이트 패턴
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
#include <iostream> #include <conio.h> #include <Windows.h> #define KEY_ESC 27 using std::cout; using std::endl; class CAccount { public: enum { STATE_IDLE, STATE_INPUT, STATE_WAIT_ACK, STATE_MAX }; public: int m_iState; CAccount(); void OnIdle(); void OnInput(); void OnWaitAck(); void SetState(int iState); void Render(); }; CAccount::CAccount() { m_iState = STATE_IDLE; } void CAccount::OnIdle() { cout<< "OnIdle()"<<endl; } void CAccount::OnInput() { cout<<"OnInput()"<<endl; } void CAccount::OnWaitAck() { cout<<"OnWaitAck"<<endl; } void CAccount::SetState(int iState) { m_iState = iState; } void CAccount::Render() { static void (CAccount::*f[])()= //배열 { &CAccount::OnIdle, &CAccount::OnInput, &CAccount::OnWaitAck }; if(m_iState >= 0 && m_iState <STATE_MAX) { (this->*f[m_iState])(); } } void main() { CAccount account; int ch=0; while(ch!=KEY_ESC) { if(kbhit()) { ch=getch(); if(ch=='1') account.SetState(CAccount::STATE_IDLE); else if(ch=='2') account.SetState(CAccount::STATE_INPUT); else if(ch=='3') account.SetState(CAccount::STATE_WAIT_ACK); } Sleep(500); account.Render(); } } |
RUNTIME_CLASS 메크로 사용
RUNTIME_CLASS(CAlpha)
실행시에 객체의 클래스 이름얻기
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
#include "stdafx.h" #define DEBUG class CObject { public: virtual char* GetClassName() const{ return NULL;} }; class CMyClass : public CObject { public: static char lpszClassName[]; virtual char* GetClassName() const { return lpszClassName; } }; char CMyClass::lpszClassName[]="CMyClass1"; void main() { CObject *p; p=new CMyClass; printf("%s",p->GetClassName()); #ifdef DEBUG //cmd char e; scanf("%c",&e); #endif } 메크로 사용 #include "stdafx.h" #define DEBUG #define DECLARE_CLASSNAME(s) static char lpszClassName[] #define IMPLEMENT_CLASSNAME(s) char s##::lpszClassName[]=(#s) class CObject { public: virtual char* GetClassName() const{ return NULL;} }; class CMyClass : public CObject { public: //static char lpszClassName[]; DECLARE_CLASSNAME(CMyClass); virtual char* GetClassName() const { return lpszClassName; } }; //char CMyClass::lpszClassName[]="CMyClass1"; IMPLEMENT_CLASSNAME(CMyClass); void main() { CObject *p; p=new CMyClass; printf("%s",p->GetClassName()); #ifdef DEBUG //cmd char e; scanf("%c",&e); #endif } |
소멸자에서 가상함수 호출
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
#include "stdafx.h" #include <stdio.h> #define DEBUG class CBase{ public: CBase(){ DoVirtual();//가상함수를 호출 X } ~CBase(){ DoVirtual();//가상함수를 호출 O } void DoIt() { DoVirtual();//가상함수를 호출 O } virtual void DoVirtual() { printf("CBase\n"); } }; class CDerive : public CBase { public: virtual void DoVirtual() { printf("CDerive\n"); } }; void main() { CDerive b; b.DoIt(); #ifdef DEBUG //cmd char e; scanf("%c",&e); #endif } |
가상 소멸자
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
#include "stdafx.h" #include <stdio.h> #include <string.h> #define DEBUG class A{ char* a; public: A(char* s){ a=new char[strlen(s)+1]; strcpy(a,s); } virtual ~A(){ delete[] a; printf("Destructor of class A\n"); } virtual void Print() { printf("%s\n",a); } }; class B : public A{ char* b; public: B(char* s,char* t):A(t){ b=new char[strlen(s)+1]; strcpy(b,s); } virtual ~B(){ delete[]b; printf("Destructor of class B\n"); } virtual void Print(){ A::Print(); printf("%s\n",b); } }; void main() { A* pA; pA=new B("hello","world"); pA->Print(); delete pA; #ifdef DEBUG //cmd char e; scanf("%c",&e); #endif } |
상위 클래스로 사용될 것 같은 클래스의 생성자에서 동적으로 메모리를 할당하는 경우, 소멸자를 가상으로 선언하라.
가상함수를 이용한 객체지향 모델
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
#include "stdafx.h" #define DEBUG class CBase { public: void Print() { printf("pre virtual\n"); OverrideMe(); printf("post virtual\n"); } virtual void OverrideMe() { printf("CBase\n"); } }; class CDerive : public CBase { public: void Draw() { printf("draw\n"); } virtual void OverrideMe() { CBase::OverrideMe();//가상함수의 일반적인 설계규칙은 //베이스 클래스의 가상함수에 기능을 확장하는 것이다. printf("CDerrive\n"); } }; void main() { CDerive d; d.Print(); #ifdef DEBUG //cmd char e; scanf("%c",&e); #endif } |
pre virtual CBase CDerrive post virtual