반응형

C++ 패턴 : 동적 싱글턴(Dynamic Singleton)

정리하게 된 배경

 은근히 자주 사용되지만, 가끔 기억이 안나서 잘 못 작성한 코드의 오류를 한참 고민을 했기 때문에 후에 있을 시간을 절약하기 위해 기록을 한다.


싱글턴 패턴

 영문으로는 Singleton이라 하기 때문에 싱글톤이라 표기 한곳도 의외로 많지만, 위키백과에서는 싱글턴으로 표기를 하기 때문에 여기서는 싱글턴으로 표기를 하였다. 싱글턴 패턴도 여러 종류가 있지만, 실용적으로 자주 사용되는 동적 싱글턴 패턴에 대해서 소스코드를 적는다.


 싱글턴 패턴은 이름에서도 알 수 있 듯이 하나만 있다는 의미를 내포하고 있다. 즉, 실질적인 객체는 오직 하나이다. 싱글턴 객체를 사용하기 위해서는 싱글턴 내부에 선언되어 있는 인스턴스객체에 접근해서 사용이 가능하다. C/C++에서는 포인터의 개념을 들어 설명을 하면 이해가 쉽지만(물론 포인터를 이해했다는 전제하에) 포인터가 없는 다른 언어에서는 종종 인스턴스 참조와 인스턴스 생성간 혼란이 있는 듯하다.

 

 논리(이론)적 구성은 단하나의 객체 혹은 인스턴스가 존재해야 하며, 추가로 선언을 못하게 해야 한다. 여기서 동적 싱글톤의 경우 프로그램 시작과 관계없이 싱글턴의 인스턴스를 받아오려는 순간 생성이 되어 생성시점이 동적인 특징이 있다.


소스코드


// Singleton.hpp
#include <iostream>

class Singleton
{
private:
    Singleton(void);
    ~Singleton(void);
    static Singleton* _instance;
public:
    static Singleton* getInstance(void);
    void print(void);
};


// Singleton.cpp
#include "Singletion.hpp"

using namespace std;

Singleton* Singleton::_instance = nullptr;

Singleton* Singleton::getInstance(void)
{
    if(nullptr == _instance)
        _instance = new Singleton;
    return _instance;
}

void Singleton::print(void)
{
    cout << "singletion!" << endl;
}


// main.cpp
#include "Singleton.hpp"

Singleton* ins = Singleton::getInstance();
ins->print();
// or
Singleton::getInstance()->print();


주의할 점

 파일을 hpp에서 getInstance()를 정의할 경우에는 상관이 없지만, cpp에서 정의를 할 경우 static 키워드가 앞에 있어서는 안된다. 만약 사용한다면 문법적인 오류로 에러 메시지를 확인하게 된다.


참고자료

경험




반응형
반응형

싱글턴 패턴(Singleton pattern) 예제코드


사용하게 된 계기

 작성한 클래스로 객체를 생성해서 사용을 하는데, 굳이 여러개의 객체를 만들 필요가 없지만, 자주 호출되는 경우 사용하는 것이 싱글턴이고, 웹 프로그램에서도 주로 네트워크라던가 감시하는 종류의 역할을 하는 프로그램의 경우에는 여러객체를 생성하게 되면 상당히 낭비를 하게 된다는 것을 알게 된다.

 이러한 코딩 패턴을 싱글턴(필자는 싱글톤이라고 종종 읽기도 한다)이라고 하고 이러한 패턴은 대부분 프로그래밍 언어에서 디자인이 가능하다. 싱글턴의 자세한 패턴은 "디자인 패턴"에 대해서 공부를 하도록 하자. 타입스크립트(TypeScript)는 비교적 C#과 비슷한 문법을 유지하고 있기 때문에 경력자라면 쉽게 구현하여 사용할 수 있다.


싱글턴 조건

1. 객체가 하나만 존재해야 한다. 객체를 추가로 생성해도 객체는 하나가 되어야 한다.

2. 해당 객체의 메서드는 인스턴스를 통해서 사용할 수 있다.


타입스크립트의 싱글턴 예제들

예제1

 가장 기본적인 예제로 클래스가 생성되는 과정에서 인스턴스에 자기자신이 선언이 된다.

class Singleton
{
    private static _instance: Singleton = new Singleton;
    constructor()
    {
        if(Singleton._instance){
            throw new Error("Error: Instantiation failed: Use Singleton.getInstance()");
        }
        Singleton._instance = this;
    }
    public static getInstance(): Singleton
    {
        return Singleton._instance;
    }
    //...
}
// 싱글턴 사용을 위한 인스턴스
var singleton = Singleton.getInstance();

참조: http://www.codebelt.com/typescript/typescript-singleton-pattern/


예제2

 타입스크립트 2.0 이후부터 권장이 되는 방식으로 앞의 예제1의 경우 클래스가 정의 된가 동시에 싱글턴의 객체가 생성이 된다. 하지만, 이 방식의 경우 코드를 보면 알겠지만, 인스턴스를 최초로 받을 때 객체가 생성이 되기 때문에 라이브러리로 만들어서 사용한다면, 불필요한 객체롤 아예 만들지 않을 수 있기 때문에 위의 방식보다 좀 더 나은 방식이다.

class Singleton
{
    private static _instance: Singleton;
    constructor()
    {
        //...
    }
    public static get Instance()
    {
        return this._instance || (this._instance = new this());
    }
    //...
}
// 싱글턴 사용을 위한 인스턴스
var singleton = Singleton.Instance;


참조: https://github.com/Microsoft/TypeScript/issues/2341


그밖의 예제

검색을 좀 해보면 상당히 많은 방식들을 찾을 수 있다. 아래의 스택오버플로워(stackoverflow)의 채택된 답변외에도 다양한 답들이 있는 것을 확인할 수 있다.

스택오버플로워 질문: http://stackoverflow.com/questions/30174078/how-to-define-singleton-in-typescript

반응형

+ Recent posts