싱글톤 패턴 1
Engine > pch.h
// pch.h: 미리 컴파일된 헤더 파일입니다.
// 아래 나열된 파일은 한 번만 컴파일되었으며, 향후 빌드에 대한 빌드 성능을 향상합니다.
// 코드 컴파일 및 여러 코드 검색 기능을 포함하여 IntelliSense 성능에도 영향을 미칩니다.
// 그러나 여기에 나열된 파일은 빌드 간 업데이트되는 경우 모두 다시 컴파일됩니다.
// 여기에 자주 업데이트할 파일을 추가하지 마세요. 그러면 성능이 저하됩니다.
#ifndef PCH_H
#define PCH_H
// 여기에 미리 컴파일하려는 헤더 추가
#include "framework.h"
//new
#include <Windows.h>
#endif //PCH_H
Engine > 01. Engine > CEngine.h (new)
#pragma once
class CEngine
{
// 데이터 영역 메모리 : 전역 변수
// 프로세스 시작할때 초기화
// 프로세스 종료시 해제
// 프로세스가 실행도중 상시 유지되는 메모리
private:
static CEngine* g_This;
private:
HWND m_hMainWnd;
public:
// 정적 맴버함수 : 객체가 없어도 호출 가능
static CEngine* GetInst()
{
if (g_This == nullptr) {
g_This = new CEngine;
}
return g_This;
}
static void Destroy() {
delete g_This;
g_This = nullptr;
}
private:
CEngine();
};
Engine > 01. Engine > CEngine.cpp (new)
#include "pch.h"
#include "CEngine.h"
CEngine* CEngine::g_This = nullptr;
CEngine::CEngine() {
}
Client > Client.cpp
...
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
//old
//int value = Add(10, 20);
MyRegisterClass(hInstance);
hInst = hInstance;
HWND hWnd = CreateWindowW(L"Test", L"MyGame", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, true);
UpdateWindow(hWnd);
//new
// CEngine 객체 초기화
CEngine* pEngine = CEngine::GetInst();
HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_CLIENT));
MSG msg;
while (true)
{
if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
{
if (WM_QUIT == msg.message)
break;
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else
{
// Game Engine 실행
}
}
//new
CEngine::Destroy();
return (int) msg.wParam;
}
...
싱글톤 패턴 2
Engine > 01. Engine > CEngine.h (new)
#pragma once
class CEngine
{
public:
static CEngine* GetInst() {
// 데이터 영역 메모리를 사용한다.
// 함수호출이 끝났어도 데이터는 삭제되지 않는다.
static CEngine mgr;
return &mgr;
}
private:
CEngine();
};
Engine > 01. Engine > CEngine.cpp (new)
#include "pch.h"
#include "CEngine.h"
//old
//CEngine* CEngine::g_This = nullptr;
CEngine::CEngine() {
}
Client > Client.cpp
...
}
//new
//CEngine::Destroy();
return (int) msg.wParam;
}
이방식은 Destroy() 가 필요없다.
프로그램 도중에는 삭제 시킬수 없기 때문에..
디폴트 복사생성자 문제
Client > Client.cpp
CEngine* pEngine = CEngine::GetInst();
CEngine e = *pEngine;
우리가 안막아두었던 default 복사생성자때문에 위에 코드로 싱글톤도 객체생성이 가능해버린다.
Engine > 01. Engine > CEngine.h
#pragma once
class CEngine
{
//new
private:
HWND m_hMainHwnd;
POINT m_Resolution;
public:
static CEngine* GetInst() {
static CEngine mgr;
return &mgr;
}
private:
CEngine();
//new
public:
CEngine(const CEngine& _origin)
: m_hMainHwnd(_origin.m_hMainHwnd)
, m_Resolution(_origin.m_Resolution)
{
}
};
위 코드처럼 생긴 CEngine 이 있기때문에 복사 생성자가 생략된 거다.
public:
//old
//CEngine(const CEngine& _origin)
// : m_hMainHwnd(_origin.m_hMainHwnd)
// , m_Resolution(_origin.m_Resolution)
//{
//}
//new
CEngine(const CEngine& _origin) = delete;
};
위와 같이 기본 복사생성자를 사용하지 못하게 막자.
Client > Client.cpp
CEngine* pEngine = CEngine::GetInst();
//old
//CEngine e = *pEngine;
Engine > 01. Engine > CEngine.h
private:
CEngine();
//old
//public:
CEngine(const CEngine& _origin) = delete;반응형