Written by
Sangwan Kwon
on
on
Singleton with Modern c++
Singleton Pattern
싱글턴 패턴(Singleton pattern)을 시스템에서 정확히 하나의 인스턴스만 유지해야 하는 클래스에 적용하는 디자인 패턴이다.
기존 C++에서의 싱글톤 패턴 구현은 static 키워드로 구현 되어 하나의 인스턴스를 생성하도록 하였다. 하지만 static 키워드로의 구현은 멀티-스레딩환경에서 안전하지 않다. (Non-Thread Safe)
Singleton with Modern C++
C++11 부터 std::once_flag를 사용하여 Thread-Safe하게 싱글톤 패턴을 구현할 수 있다.
Singleton Usage
데이터베이스 커넥션을 위한 클래스나 로그를 찍기 위한 클래스 등에 사용한다.
Singleton Implementation Tatic
- 생성자를 숨기고 인스턴스 게터 함수(Getter)를 제공 한다.
- 복사 생성자와 이동 생성자를 삭제 한다.
- std::once_flag를 사용하여 인스턴스 생성 과정을 Thread-safe하게 한다.
- std::unique_ptr을 사용하여 하나의 인스턴스를 보장 한다.
Singleton Declaration
위 조건(1~4)에 따른 헤더파일 정의부는 아래와 같다.
// singleton.hxx
#pragma once
#include <memory>
#include <mutex>
#include <iostream>
class Singleton final {
public:
~Singleton() = default;
Singleton(const Singleton &) = delete;
Singleton(Singleton &&) = delete;
Singleton &operator=(const Singleton &) = delete;
Singleton &operator=(Singleton &&) = delete;
static Singleton& GetInstance(void);
private:
Singleton() = default;
static std::unique_ptr<Singleton> instance;
static std::once_flag flag;
};
Singleton Definition
3번 조건과 디버깅을 위한 구현부는 아래와 같다.
// singleton.cpp
#include "singleton.hxx"
std::unique_ptr<Singleton> Singleton::instance = nullptr;
std::once_flag Singleton::flag;
Singleton& Singleton::GetInstance(void)
{
std::call_once(Singleton::flag, []() {
std::cout << "Create Instance." << std::endl;
Singleton::instance.reset(new Singleton);
});
std::cout << "Get Instance." << std::endl;
return *Singleton::instance;
}
Singleton Testing
아래는 테스트를 위한 코드이다. 첫 호출 시에만 인스턴스 생성 코드가 동작하는 것을 확인 할 수 있다.
// g++ main.cpp singleton.cpp -std=c++11 -pthread
// main.cpp
#include "singleton.hxx"
int main() try {
Singleton::GetInstance();
Singleton::GetInstance();
Singleton::GetInstance();
return 0;
} catch (std::exception& e) {
std::cout << e.what() << std::endl;
}