Singleton pattern
: 오직 유일한 하나의 객체만을 만드는 design pattern
Singleton pattern 구현 방법
1) 객체의 생성을 막기 위하여 생성자를 private 영역에 정의한다.
2) 생성된 객체 없이도 함수를 호출할 수 있기 위해서 정적 함수를 제공한다.
3) 객체의 복사와 대입을 금지하기 위하여 복사 생성자와 대입 연산자 함수를 private 영역에 정의한다.
하지만 Cursor class 내의 함수에서 일어나는 복사, 대입연산자로 인해
singleton 개념이 침해되는 것을 막을 수 없다.
따라서 객체 내부에서 일어나는 복사, 대입 연산자를 막기 위해서 함수를 선언만 한다.
하지만 함수의 정의를 하지 않고, private 영역에 선언만 해버리면, 컴파일 타임에는 문제가 없지만 링킹 타임에 에러가 발생한다.
또한 실제 개발할 때는 header와 source 코드가 나뉘기 때문에
header 파일에 위 처럼 선언 부분만 되어 있다면
이 객체를 사용하는 개발자는 이것이 선언만 되어 있는지 정의도 되어 있는지 알 수 없다.(실제 source code를 살펴보지 않는한..)
그래서 C++11 에서 제공하는 delete 키워드를 사용한다.
하지만 구현 할 때마다 singleton pattern을 매번 구현하는 것이 번거롭기 때문에
metacode 와 template 을 이용해서 좀 더 간단하게 singleton 을 구현한다.
1) 복사, 대입연산자를 매크로로 선언한다.(MAKE_NO_COPY)
2) 생성자, static 변수, 복사, 대입 연산자를 하나의 DECLARE 패턴으로 사용한다.
3) 구현 코드도 매크로로 치환한다.
구현 코드를 객체 내부에서 밖으로 가지고 나와서
생각해보면 매크로로 만드는데 조금더 쉽게 생각할 수 있다.
최종적으로 정리된 매크로로 구현한 Singleton pattern
Singleton 을 사용할 때 발생하는 concurrency 문제를 살펴보자.
일반적으로 multi thread 프로그래밍을 구현할 때,
critical section 의 자원을 동기화하기 위해 mutex 를 사용한다.
하지만 new Cursor에서 메모리 할당이 실패하면, exception 이 발생하게 된다.
예외가 발생한 시점 부터 이전으로 stack unwinding 한다.
이 상황에서 mutex.lock()이 걸려 있는 상태가 유지되어 deadlock 이 발생하게 된다.
이 문제를 해결하기 위한 RAII(Resource Acquisition Is Initialisation) 기법을 사용한다.
RAII 기법의 기본적인 원리는
C++은 지역 객체가 사라질 경우 소멸자가 불려지는 것을 보장하고,
혹은 heap 에 할당된 객체를 delete 할 경우 소멸자가 호출되는 점을 이용한다.
이렇게 block 내에서 lock 을 해제해주는 테크닉을 auto lock 혹은 scope lock 이라 한다.
C++11 에서는 위와 같은 auto lock 기법을 lock_guard class로 지원한다.
피드 구독하기:
댓글 (Atom)
[C++] meta programing
재귀 호출에 관해 template meta programming 을 적용한 예제를 살펴보자. #include using namespace std; int fact(int n){ if(n factorial 연산을 하는 일반적인 재귀 호출 함...
-
Smart Pointer : 포인터처럼 동작하며 자동으로 메모리를 해제하고 안전하게 resource를 관리하도록 돕는 객체 포인터는 소멸자가 호출되지 않아 memory leak이 발생한다. Java, C#같은 VM이 있는 언어는 VM에서 G...
-
nullptr 란? C++11 에서 지원하는 null pointer 상수 먼저 pointer 가 초기화될 수 있는 정수 값을 살펴보자. 정수 0은 모든 타입의 포인터에 암시적 형변환을 통해서 초기화 값으로 사용될 수 있다. 하지만 그 이...
-
자료 구조를 순회하여 데이터에 접근하는 방법을 살펴보자. Container 에 저장된 데이터에 접근하기 위해 대표적으로 Iterator의 begin(), end() function 을 사용한다. 하지만 위 예제에서 show() 함수에 배열이...
댓글 없음:
댓글 쓰기