Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |
Tags
- 책추천
- 말해보카
- 실용주의 사고와 학습
- 귀찮게 받아서 죄송해요
- 핑거드럼
- BookReview
- 공부법
- 개발자
- trigger
- 책리뷰
- 새로운 것을 좋아하는 사람
- sampler
- 영어공부
- 일하기로 결정
- PragmaticThinking&Learning
- 의심하지말자
- Pragmatic Thinking&Learning
- TheBygoneDays
- 자기계발서
- 개발자 책 추천
- 포스팅러닝
- 일기
- 개발자입문
- 석화 따뜻한데서 자자
- DRD4 III 7 repeat
- 일상
- 메뉴얼 한글번역
- BLOCK
- notion2tstory
- 잘잘잘
Archives
- Today
- Total
BLOCK
싱글턴 패턴(Singleton) 본문
728x90
싱글턴 패턴(Singleton)
싱글턴은 클래스에 인스턴스가 하나만 있도록 하면서 이 인스턴스에 대한 전역 접근(액세스) 지점을 제공하는 생성 디자인 패턴입니다.
1. 싱글턴 패턴(Singleton)
싱글턴 주요 키워드
- 전역적인 접근을 위한 정적변수사용
- 생성자보호를 위해서 생성자를 private 으로 설정한다.
- 복사생성자와 복사대입연산자를 막아서 단일 인스턴스 원칙을 고수합니다.
1-1) 동적 할당 방식
싱글턴 객체의 instance를 생성할때 new연산자를 이용해서 생성하는 방식
class Singleton
{
public:
static Singleton* GetInstance()
{
if (instance == nullptr)
{
instance = new Singleton(); // 동적 할당
}
return instance;
}
static void DestroyInstance() // 동적할당 객체는 수동으로 삭제 필요
{
delete instance;
instance = nullptr;
}
Singleton(const Singleton&) = delete; // 복사생성자 삭제
Singleton& operator=(const Singleton&) = delete; // 복사대입 연산자 삭제
private:
Singleton() { std::cout << "make ton" << std::endl; }
~Singleton() { std::cout << "delete ton" << std::endl; }
static Singleton* instance; // 전역적인 접근을 위한 정적 멤버변수
};
Singleton* Singleton::instance = nullptr; // 정적변수의 초기화는 클래스 외부에서 해준다
장점
- 소멸시점이 자유롭습니다.
단점
- delete 를 잊으면 메모리누수의 위험이 있습니다.
1-2) 정적 지역 변수 방식
싱글턴 객체를 생성할때 GetInstance() 함수안에서 정적지역변수 (static local variable)를 직접 생성하는 방식
class Singleton
{
public:
static Singleton& GetInstance()
{
static Singleton instance; // 프로그램 종료 시 자동 소멸
return instance;
}
Singleton(const Singleton&) = delete; // 복사생성자 삭제
Singleton& operator=(const Singleton&) = delete; // 복사대입 연산자 삭제
private:
Singleton() { std::cout << "make ton" << std::endl; }
~Singleton() { std::cout << "delete ton" << std::endl; }
};
C++11 이전에는 정적 지역 변수를 초기화하는 과정에서 멀티스레드 환경에서 경쟁 조건(Race Condition) 이 발생할 수 있었으나
C++11에서는 함수 내부에 정의된 정적 변수의 초기화가 스레드로부터 안전하도록 보장되어 정적 지역 변수 방식을 사용할 수 있게 되었습니다.(이 기능을 비공식적으로 Magic Static이라고 부르고 있습니다.)
장점
- 지역변수이기 때문에 프로그램 종료시 자동으로 소멸하여 메모리관리에 용이합니다.
- 메모리누수 위험이 없습니다.
- 동적할당 과정이 없어 속도에 유리합니다.
- C++11 이후를 기준으로 스레드 안정성을 보장합니다.
단점
- 소멸시점이 프로그렘 종료시로 고정됩니다.
1-3) CRTP를 이용한 방식
싱글턴의 형태를 갖춘 템플릿을 만들어두고 상속을 통해 다양한 클래스에 쉽게 싱글턴 패턴을 적용시키는 방식
파생클레스에서 내부멤버에 접근 할 수 있도록 하기위해 template에서 생성자를 protected 로 지정해줍니다.
CRTPBase에서 파생클래스의 생성자에 접근할 수 있도록 friend class선언을 해줍니다.
이때 protected 지정되어있는 GetInstance() 함수에 접근하기 위해 public상속을 해주어야 합니다.
template<typename T>
class SingletonBase
{
public:
static T& GetInstance()
{
static T instance; // 정적 지역 변수로 단일 인스턴스 보장
return instance;
}
protected:
SingletonBase() = default;
~SingletonBase() = default;
// 복사와 대입 방지
SingletonBase(const SingletonBase&) = delete;
SingletonBase& operator=(const SingletonBase&) = delete;
};
class MyClass: public SingletonBase<MyClass>
{
public:
void func(){/*필요한 함수구현*/}
private:
MyClass() {}
~MyClass() {}
// 싱글턴 private 생성자에 접근 가능하도록 friend 선언
friend class SingletonBase<MyClass>;
};
장점
- 컴파일 타임 정적 다형성 제공
- 인라인 최적화 가능
- 가상 함수 오버헤드 제거
- 코드 재사용성 및 확장성 향상.
단점
- 템플릿 복잡성 증가
- 난해한 컴파일 에러 메시지
- 빌드 시간 증가
- 디버깅 어려움
'BLOCK::MATERIAL > BLOCK::CODE' 카테고리의 다른 글
고도엔진 VisualStudio로 실행하기 (0) | 2025.03.02 |
---|
Comments