싱글턴은 애플리케이션 전체에서 단 하나만 존재해야 하는 상황을 처리하기 위해 고안되었다. 동일한 데이터를 여러 번 로딩하여 메모리를 낭비할 필요가 없기 때문이다. 싱글턴을 사용 시에는 멀티스레드 안정성을 고려해야 하며 두 번 생성되는 일을 막아야 한다.
JAVA 에서는 syncronized 키워드가 제공되어 쉽게 처리할 수 있으나 C++에서는 이중 검증 락킹(double-check locking), mutex, atomic 등 여러 가지가 고안되었다.
C++에서는 컴파일러 버전별로 구현이 조금식 다르다. 이는 키워드나 stl 의 특정함수 지원 유무에 따라 달라진다. 아래는 C++ 에서 싱글톤 구현 예시이다.
#include <new>
#include <memory>
#include <mutex>
#include <stdio.h>
class Singleton
{
public:
static Singleton& getInstance();
void log(){
printf("instance: %p", __instance.get());
}
~Singleton(){
printf("delete instance : %p", this);
}
private:
Singleton() = default;
Singleton(const Singleton &) = delete;
Singleton &operator=(const Singleton &) = delete;
static std::unique_ptr<Singleton> __instance;
static std::once_flag __once;
};
std::unique_ptr<Singleton> Singleton::__instance;
std::once_flag Singleton::__once;
Singleton&
Singleton::getInstance()
{
std::call_once(__once, []() {
__instance.reset(new Singleton);
printf("create instance : %p\n", __instance.get());
});
return *__instance.get();
}
struct Database
{
protected:
Database() {}
public:
static Database& get() {
// C++11 이상 버전에서는 스레드 세이프 함
static Database database;
return database;
}
Database(Database const&) = delete;
Database(Database&&) = delete;
Database& operator=(Database const&) = delete;
Database& operator=(Database&&) = delete;
// 생성자 은닉 복제/이동 생성자/연산자 삭제
};
/* C++ 11 이전 delete 키워드를 사용할수 없다 */
struct Database
{
public:
static Database& get() {
static Database database;
return database;
}
private:
Database() {;}
Database(Database const&) {;}
Database(Database&&) {;}
Database& operator=(Database const&) {;}
Database& operator=(Database&&) {;}
};
RAII idiom (0) | 2021.05.07 |
---|---|
핌플 이디엄 Pimpl idiom (0) | 2021.05.07 |
빌더 패턴 사용 이유 (0) | 2021.05.07 |
빌더 패턴 Build pattern (0) | 2021.05.07 |
모노스테이트 패턴 Monostate pattern (0) | 2021.05.07 |
댓글 영역