Singleton Pattern(싱글톤 패턴)
네트워크를 배우는 단계에서
DB, Socket 의 객체를
1개만 생성되도록 강제하고
모든 GUI 객체에서 공유하는
패턴을 기반으로 로직 구현하는 연습한다.
Singleton Pattern(싱글톤 패턴)
: 클래스의 인스턴가 1개만 생성되도록 강제하는 방식
: 1개의 인스턴스를 모든 객체에서 공유하는 방식
1. 기본 싱글톤
1.1. 기본 개념
#include <iostream>
class Singleton
{
private:
// new 를 사용한 instance 생성을 제한되도록 생성자를 private로 선언 한다.
Singleton(){};
~Singleton() {};
Singleton(const Singleton& other);
// 전역 선언, 생성 순서에 기준이 없다.
static Singleton instance;
public:
// Singleton static 객체를 반환하는 GetInstance 함수로 접근한다.
static Singleton& GetInstance()
{
return instance;
}
};
int main(void)
{
Singleton& s1 = Singleton::GetInstance();
}
문제점
: 전역 객체 선언시, 전역으로 선언된 싱글톤 객체의 생성 순서가 명확하지 않다.
싱글톤 객체를 참조하는 전역 객체 및 지역 객체들의 생성 시점이 명확하지 않아 참조 문제가 발생한다.
// num4가 먼저 될 생성 될 수도 있고 num2가 먼저 될 수도 있다. 알 수 없다.
static int num1 = 0;
static int num2 = 0;
static int num3 = 0;
static int num4 = 0;
2. Dynamic Singleton(동적 싱글톤)
Dynamic(뜻:동적), 늦은 초기화
전역 객체를 포인터로 접근하고, 함수 호출 시 동적으로 할당하여 으로 객체의 생성 시점을 제한한다.
기본 싱글톤의 생성 시점 문제를 해결할 수 있다.
#include <iostream>
class Dynamic_Singleton {
private:
Dynamic_Singleton() {}
~Dynamic_Singleton() {}
Dynamic_Singleton(const Dynamic_Singleton& ref) {}
Dynamic_Singleton& operator=(const Dynamic_Singleton& ref) {}
static Dynamic_Singleton* instance;
public:
static Dynamic_Singleton* getIncetance() {
if(instance == NULL)
instance = new Dynamic_Singleton();
return instance;
}
};
Dynamic_Singleton* Dynamic_Singleton::instance = NULL;
int main(void) {
Dynamic_Singleton* s1 = Dynamic_Singleton::getIncetance();
Dynamic_Singleton* s2 = Dynamic_Singleton::getIncetance();
if(s1 == s2)
std::cout << "O 같습니다." << std::endl;
else
std::cout << "X 다릅니다." << std::endl;
return 0;
}
문제점
"new"로 동적 메모리를 할당을 했기 때문에, 프로그램이 종료될 때 까지 Heap 메모리에 계속 생성되어있다.
싱글톤 클래스의 경우에는 객체가 단 한번만 생성되기 때문에 메모리 누수와 같은 문제에 직면할 가능성도 한없이 낮다.
하지만, Dynamic Singleton 동적 할당이기에 해제하는 함수를 만들거나 소멸자, friend를 이용해서 직접 관리해야 한다.
class Dynamic_Singleton {
...
public:
...
void Dynamic_Singleton::DestroyInstance()
{
if (!instance)
return;
delete instance;
instance = nullptr;
}
}
Static Local Singleton(정적 싱글톤)
#include <iostream>
class Sock_Singleton
{
private:
Sock_Singleton() {}
~Sock_Singleton() {}
Sock_Singleton(const Sock_Singleton& ref) {}
Sock_Singleton& operator=(const Sock_Singleton& ref) {}
public:
static Sock_Singleton& getIncetance() {
static Sock_Singleton instance;
return instance;
}
};
int main(void) {
Sock_Singleton& s1 = Sock_Singleton::getIncetance();
Sock_Singleton& s2 = Sock_Singleton::getIncetance();
if(&s1 == &s2)
std::cout << "O 같습니다." << std::endl;
else
std::cout << "X 다릅니다." << std::endl;
return 0;
}