꿈꾸는 시스템 디자이너

C++ 싱글턴 패턴(Singleton Pattern)의 이해 본문

Development/C++

C++ 싱글턴 패턴(Singleton Pattern)의 이해

독행소년 2014. 9. 19. 10:44

싱글턴 패턴이란 특정 클래스의 인스턴스를 1개만 생성되도록 제한하고 이를 공유하는 방법이다.


<SingletonClass.h>

#ifndef SINGLETONCLASS_H_
#define SINGLETONCLASS_H_

#include <iostream>
using namespace std;

class SingletonClass {

private:

	/**
	 * 생성자
	 * 외부에서 인스턴스를 생성할 수 없도록 private 영역에 정의하고 구현함
	 * 원리: private 영역에 생성자가 존재하므로 외부에서 SingletonClass()를 호출할 수 없음
	 */
	SingletonClass(){};

	// 싱글턴 인스턴스가 생성되었는지 여부
	static bool instanceFlag;

	// 싱글턴 인스턴스
	static SingletonClass* instance;

	// private 멤버 변수(멤버 변수!!!!!)
	int total;

public:

	// 싱글턴 인스턴스를 반환할 멤버함수
	static SingletonClass* getInstance();

	// 소멸자, instanceFlag를 false로 변경
	virtual ~SingletonClass(){
		instanceFlag = false;
	};

	// value의 값을 증가 시킴
	void addValue(int value);
	// value 값을 반환
	int getTotalValue();

};

#endif /* SINGLETONCLASS_H_ */

싱글턴 패턴을 다시 설명하면, new 키워드로 클래스의 인스턴스를 직접 생성할 수 없도록 하고, 해당 클래스내의 특정 함수로 부터 해당 클래스의 인스턴스를 전달 받는 방식이다.

생성되지 않은 인스턴스내 함수를 통해 인스턴스를 받으려면, 그 함수는 static 함수가 되어야 한다.


위의 소스를 보면,

new 키워드로 인스턴스가 생성되는 것을 방지하기 위해 생성자를 private 영역으로 이동시켰다.

그리고 글래스의 인스턴스를 static 포인터 멤버 변수로 정의하고(line 22), 그 인스턴스를 반환하는 static 멤버 함수인 getInstance()를 선언하고 있다(line 30).


추가로 tatal이라는 int형 멤버변수를 선언하여 외부에서 참조할때 어떻게 변하는지를 확인할 것이다.


<SingletonClass.cpp>

#include "SingletonClass.h"

/*
 * 이클립스에 의해 자동 생성된 생성자와 소멸자의 템플릿
 * - 생성자: 헤더파일에서 private 생성자로 선언 및 구현함
 * - 소멸ㅈ: 헤더파일에서 public 소멸자로 선언 및 구현함
 * 즉, 소스코드에서는 구현하지 않음(해서는 안됨)
SingletonClass::SingletonClass() {
}

SingletonClass::~SingletonClass() {
}
*/

/*
 *  헤더에서 선언한 static 멤버들을 다시한전 선언한다.
 * 이는 static 멤버를 일반 멤버함수처럼 참조할 수 있도록 한다(?)
 */
bool SingletonClass::instanceFlag = false;
SingletonClass* SingletonClass::instance = NULL;

// 싱글턴 인스턴스를 반환할 멤버함수
SingletonClass* SingletonClass::getInstance(){
	if(!instance){
		instance = new SingletonClass();
		instanceFlag = true;
	}
	return instance;
}

// total의 값을 증가 시킴
void SingletonClass::addValue(int value){
	total = total + value;
}
// totla 값을 반환
int SingletonClass::getTotalValue(){
	return total;
}

C++ 파일을 보면, line 19~20까지 헤더파일에서 정의한 static 멤버변수를 다시 선언하고 초기화하고 있다. 이는 파일내 일반 함수들이 static 멤버들을 일반 멤버처럼 참조할 수 있도록 함인거 같다.(이렇게 선언하지 않으면 에러가 발생한다.)


getInstance함수에서는 인스턴스가 이미 존재하면 존재하는 인스턴스를 반환하고, 없을 경우에만 새롭게 직접 생성해서 반환한다.


그리고 tatal의 값을 증가시키고 반환하는 테스트용 함수들도 구현했다.


<SingleTonTest.cpp>

#include 
#include "SingletonClass.h"
using namespace std;

int main() {
	cout << "SingleTonTest" << endl; // prints SingleTonTest

	// SingletonClass의 인스턴스 변수를 포인터 변수 형태로 선언
	SingletonClass *ins1, *ins2, *ins3;

	// 각각의 변수에 인스턴스를 저장
	ins1 = SingletonClass::getInstance();
	ins2 = SingletonClass::getInstance();
	ins3 = SingletonClass::getInstance();

	// 각 인스턴스별로 멤버변수 total에 10씩 증가 시키고, 그 결과를 출력
	ins1->addValue(10);
	cout << "total: " << ins1->getTotalValue() << endl;
	ins2->addValue(10);
	cout << "total: " << ins2->getTotalValue() << endl;
	ins3->addValue(10);
	cout << "total: " << ins3->getTotalValue() << endl;

	return 0;
}

SingletonClass를 이용하는 방법은 위의 코드와 같다.

SingletonClass 타입의 포인터 변수들을 선언하고, getInstance 함수를 통해 인스턴스를 획득한다.

그리고 각 인스턴스를 통해 tatal의 값을 증가시키고 그 결과를 확인한다.



결과값을 확인하면, 서로다른 인스턴스를 통해 멤버변수 total의 값을 증가시켰으나 그 값이 누적된 결과를 확인할 수 있다.

이는 각 인스턴스 변수가 실제 하나의 인스턴스를 참조하고 있음을 의미한다.

'Development > C++' 카테고리의 다른 글

Ubuntu에서 Eclipse Boost 설정  (0) 2016.11.28
C++ 클래스 상속 예제  (0) 2014.10.02
Comments