별빛의 낙하지 :: 'Framework' 카테고리의 글 목록

Search

'Framework'에 해당되는 글 1건

  1. 2012.11.17 [android] Singleton.h

[android] Singleton.h

Framework/안드로이드 2012. 11. 17. 02:20 Posted by byulbit
안드로이드 프레임웍에 있는 싱글톤은 템플릿으로 구현이 되어 있다. 

보통 다른 곳에서는 상속기반의 CRTP로 싱글톤을 구현하지만, 이와 약간 다르게 구현이 되어 있다. 

아래 소스는 멀티스레드와 관련된 기능은 제외한 안드로이드 싱글톤 템플릿 클래스이다.
#ifndef ANDROID_UTILS_SINGLETON_H
#define ANDROID_UTILS_SINGLETON_H

namespace android {

template 
class Singleton
{
public:
	static T& getInstance() {
		T* instance = sInstance;
		if(instance == 0) {
			instance = new T();					// Call Default Constructor
			sInstance = instance;
		}
		return *instance;
	}

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

private:
	Singleton(const Singleton&);					// Prohibit Copy Constructor
	Singleton& operator= (const Singleton&);		// Prohibit Copy Constructor
	static T* sInstance;							// Static Instance
};

#define ANDROID_SINGLETON_STATIC_INSTANCE(TYPE)			\
	template class Singleton< TYPE >;					\	// Default Template
	template<> TYPE* Singleton< TYPE >::sInstance(0);		// Specialization


// -----------------------------------------------
};	// namespace android
#endif

  ANDROID_SINGLETON_STATIC_INSTANCE  매크로를 이용해서 template 클래스(template class Singleton<TYPE>) 와 특수화 클래스(template<> TYPE* Singleton<TYPE>::sInstance(0) )를 만든다. 

여기서 특수화는 부분 특수화가 아닌 완전 특수화이다.   부분 특수화이든, 완전 특수화이든 특수화를 하려면 선언일지라도 특수화하지 않은 template 형태(흔히 primary라고 부른다)가 필요하다.   그래서 template class Singleton<TYPE>; 이 선언형태로 들어간다.

정적 객체를 얻어올시에는 매크로를 이용하여 한번 선언한 뒤에 

Test t = Singleton::getInstance(); 

위와 같이 일반 값이나 참조의 형태로 받으면 된다. 

getInstance() 의 반환값의 형태가 참조이기 때문에 만약 포인터 변수로 받을시에는 &연산자가 필요하다.

또한 Test 클래스는 기본 생성자(Default Constructor)를 가져야 한다는 제약이 걸려 있다.   만약 인수를 받는 생성자로 호출을 원한다면, 템플릿 클래스를 수정하여야 한다.