[c++] 간단하게 Singleton 구현하기 (feat. C++11)

달피·2021년 5월 4일
0

아래와 같이 작성하면 간단하게 Thread-safe한 Singleton이 구현된다.

class Singleton
{
public:
    static Singleton& getInstance()
    {
        static Singleton instance;
        return instance;
    }
};

이게 가능한 이유는 C+11의 아래 규칙 때문이다.

C++11에서 정적 지역변수의 초기화는 멀티스레드 환경에서도 한 번만 수행됨이 보장된다.

원문은 이렇다.

If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization.

물론 클래스의 생성자 내에서 또 다른 복잡한 동기화가 필요하거나 언어 표준을 확실하게 지원하지 않는 환경에서는 부가적인 동기화 코드들을 추가하여야 한다.

위의 코드는 동기화 문제에 대한 부분만이므로 "컴파일러가 자동으로 만들어 주는 함수들(Effective C++ 참고)"이나 상속에 대한 부분 까지 신경쓰면 아래와 같이 구성할 수 있다.
(이 때 move 생성자 및 move 할당 연산자는 소멸자나 복사 생성/할당 연산자 를 명시적으로 선언하면 자동 생성되지 않는다.)

class Singleton
{
public:
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;
    static Singleton& getInstance()
    {
        static Singleton instance;
        return instance;
    }
    void callFunction() {}

protected:
    Singleton() {}
    virtual ~Singleton() {}
};

위와 같이 만드는 singleton을 보통 Meyer’s Singleton 이라 부른다. effective 시리즈의 저자 이름인 scott meyers 에서 비롯된것으로 보인다.
간단한 Singleton을 구성할 때 템플릿 삼아 사용하면 유용하다.

하지만 구조적인 관점에서 전역 인스턴스처럼 쓰이는 Singleton은 되도록 사용하지 않는 것이 제일 좋은 것 같다. 편리함에는 반드시 따르는 위험이나 단점이 있기 마련이다.(ex. 단위테스트가 어려움)


profile
개발 오답노트

0개의 댓글