티스토리 뷰

개발/C++

디자인 패턴에 대해 알아보자 - 싱글톤 패턴

부캐: 개발하는 조대리 2024. 9. 25. 03:46
반응형

디자인패턴 - 싱글톤 패턴

 

 

 

 

 

 샘플 소스코드 다운로드

singleton_sample.cpp
0.00MB

 

 

 

 C++ 샘플 소스코드

#include <iostream>
#include <string>

class Singleton {
public:
    // 싱글톤 인스턴스를 얻는 정적 메서드
    static Singleton& getInstance() {
        static Singleton instance;  // 정적 지역 변수로 인스턴스 생성
        return instance;
    }

    // 일반적인 멤버 함수
    void setValue(const std::string& value) {
        m_value = value;
    }

    std::string getValue() const {
        return m_value;
    }

private:
    // private 생성자
    Singleton() {}

    // private 복사 생성자 및 대입 연산자 (복사 방지)
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;

    std::string m_value;
};

// 사용 예시
int main() {
    Singleton& s1 = Singleton::getInstance();
    s1.setValue("Hello");

    Singleton& s2 = Singleton::getInstance();
    std::cout << "Value from s2: " << s2.getValue() << std::endl;

    // s1과 s2는 같은 인스턴스를 참조
    std::cout << "Are s1 and s2 the same instance? " 
              << (&s1 == &s2 ? "Yes" : "No") << std::endl;

    return 0;
}

 

 

 

 구현에 대한 설명

  1. Thread-Safety: C++11 이상에서 정적 지역 변수의 초기화는 thread-safe합니다. 따라서 getInstance() 메서드 내의 정적 지역 변수 instance는 멀티스레드 환경에서도 안전하게 한 번만 초기화됩니다.
  2. 지연 초기화: getInstance() 메서드가 처음 호출될 때만 인스턴스가 생성되므로 지연 초기화가 자동으로 이루어집니다.
  3. 복사 방지: 복사 생성자와 대입 연산자를 delete 키워드로 삭제하여 인스턴스의 복사를 방지합니다.
  4. 생성자 private: 생성자를 private으로 선언하여 외부에서 직접 인스턴스를 생성할 수 없게 합니다.
  5. 전역 접근점: getInstance() 정적 메서드를 통해 싱글톤 인스턴스에 전역적으로 접근할 수 있습니다.
  6. 메모리 관리: C++에서는 정적 지역 변수를 사용함으로써 프로그램 종료 시 자동으로 소멸자가 호출되어 메모리 누수를 방지합니다.

 

 

 

 이 구현 방식의 장점

  • 간단하고 이해하기 쉽습니다.
  • C++11 이상에서 thread-safe합니다.
  • 지연 초기화를 자동으로 제공합니다.
  • 전역 변수를 사용하지 않아 초기화 순서 문제를 피할 수 있습니다.

 

 

 

 주의할 점

  • 이 패턴은 여전히 전역 상태를 만들기 때문에, 과도한 사용은 코드의 결합도를 높일 수 있습니다.
  • 단위 테스트 시 mock 객체로 대체하기 어려울 수 있습니다.

 

 


 

개인적으로 학습하면서 정리한 내용입니다.

잘못된 내용이 있을 경우 알려주시면 확인 후 수정 및 반영하도록 하겠습니다.