컴퓨터 언어/디자인패턴

싱글턴 패턴 SingleTon pattern

cepiloth 2021. 5. 7. 11:57
728x90

 

 싱글턴은 애플리케이션 전체에서 단 하나만 존재해야 하는 상황을 처리하기 위해 고안되었다. 동일한 데이터를 여러 번 로딩하여 메모리를 낭비할 필요가 없기 때문이다. 싱글턴을 사용 시에는 멀티스레드 안정성을 고려해야 하며 두 번 생성되는 일을 막아야 한다.

 JAVA 에서는 syncronized 키워드가 제공되어 쉽게 처리할 수 있으나 C++에서는 이중 검증 락킹(double-check locking), mutex, atomic 등 여러 가지가 고안되었다.

C++에서는 컴파일러 버전별로 구현이 조금식 다르다. 이는 키워드나 stl 의 특정함수 지원 유무에 따라 달라진다. 아래는 C++ 에서 싱글톤 구현 예시이다.

 

std::call_once를 이용한 구현

#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();
}

 

C++ 11 이후의 구현

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 이전의 구현

/* 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&&) {;}
};

 

 

728x90
반응형