2012-10-08 4 views
1

코드의 중요한 구성 요소 중 특정 구성 요소에 사용하는 템플릿 Singleton 클래스가 있습니다. 싱글 톤 코드 모델을 사용하는 것은이 질문의 요점이 아닙니다.템플릿의 정적 템플릿이 아닌 템플릿

이제이 템플릿을 사용하는 모든 클래스에서 공유하는 정적 카운터를이 클래스에 추가하고 싶습니다. 나 (코드가 철저하지 않습니다) 당신을 위해 코드를 보자

template <class T> 
class Singleton 
{ 
public: 
    Singleton(const std::string &name){ 
     printf("%s CTOR call #%d\n", name.c_str(), _counter); 
     _counter++; 
    } 
    virtual ~Singleton(){} 
private: 
    static int _counter; // I want this to be shared by all classes 
} 

// I can only initialize it like this; sadly 
template<class T> 
int Singleton<T>::_counter = 0; 

// main code (simplified): 
Singleton<MyClass1>("MyClass1") c1; 
Singleton<MyClass2>("MyClass2") c2; 
Singleton<MyClass3>("MyClass3") c3; 
Singleton<MyClass4>("MyClass4") c4; 

예상 출력 :

MyClass1 CTOR call #0 
MyClass2 CTOR call #1 // counter is incremented 
MyClass3 CTOR call #2 
MyClass4 CTOR call #3 

내가 얻을 것은 : 정적 INT를 의미

MyClass1 CTOR call #0 
MyClass2 CTOR call #0 // counter is not incremented 
MyClass3 CTOR call #0 
MyClass4 CTOR call #0 

아니다 공유되지만, 각 클래스에 고유합니다.

템플릿 클래스에 "not-templated"카운터가있을 수 있습니까? 머리말 전용 템플릿으로 가능합니까?

답변

1

는 다음과 같이

static int& counter() 
{ 
    static int _counter = 0; 
    return _counter; 
} 

이 당신의 싱글 회원 확인하고 대신 멤버 변수로, 이것을 사용 ...

편집 : 난 그냥 질문을 다시 읽고, 다음을 수행해야

struct Counter 
{ 
    static int& counter() 
    { 
    static int _counter = 0; 
    return _counter; 
    } 
}; 

template <class T> 
class Singleton 
{ 
public: 
    Singleton(const std::string &name){ 
     std::cout << name <<Counter::counter() << std::endl; 
     Counter::counter()++; 
    } 
    virtual ~Singleton(){} 
private: 
}; 
+1

이것은 같은 것입니다. –

+0

그래, 작동하지 않습니다 :) – Gui13

+0

오, sh * t, 나는 당신이 제대로 질문을 읽지 않았다 - 어리석은! – Nim

3

당신은 별도의 클래스에서 카운터를 넣을 수 있고, 당신은 단지 헤더 원하기 때문에뿐만 아니라 그것을 템플릿을 만들 : 예를 들어,이 또 다른 유형의 멤버합니다. 예 : 님의 솔루션을 비교 한에서

template <class T> 
struct Helper 
{ 
    static int _counter; 
}; 

template<class T> 
int Helper<T>::_counter = 0; 

struct Dummy{}; 

template <class T> 
class Singleton 
{ 
public: 
    Singleton(const std::string &name){ 
    printf("%s CTOR call #%d\n", name.c_str(), Helper<Dummy>::_counter); 
    Helper<Dummy>::_counter++; 
    } 
    virtual ~Singleton(){} 
}; 

편집이 waaaay를 물론 너무 compilcated입니다 ..하지만 그것을

+0

아니요 - 내 해결책은 어리 석었습니다. 잘못된 질문에 대답했습니다. 당신 +1을 위해서 ... :) – Nim

4

당신은 내부 static 변수로 Counter에 대해 별도의 클래스를 가질 수 있습니다 학습 템플릿 연습을 고려 . 그래서 이것은 "중첩 된 정적"카운팅과 같습니다.

구문 설탕의 경우 opeartor ++에 과부하가 걸립니다. 여기

struct Counter 
{ 
    static unsigned int value; 
    Counter& operator ++ (int) { value ++; return *this; } 
    operator unsigned int() const { return value; } 
}; 
unsigned int Counter::value = 0; 

template <class T> 
class Singleton 
{ 
public: 
    Singleton(const std::string &name){ 
     printf("%s CTOR call #%d\n", name.c_str(), s_counter.value); 
     s_counter++; 
    } 
    virtual ~Singleton(){} 
private: 
    static Counter s_counter; // shared by all classes 
}; 

working demo입니다 :

다음은 그 일의 기본 방법입니다.

UDPATE : 이것은 또 다른 방법은 별도의 .cpp 파일에 Counter::value을 정의 할 필요가 없습니다 header only template 파일을 '강요'; 그러나 나는 위의 것을 선호 할 것이다.

template<bool _true> 
struct Counter 
{ 
    static unsigned int value; 
    Counter& operator ++ (int) { value ++; return *this; } 
    operator unsigned int() const { return value; } 
}; 
template<bool _true> 
unsigned int Counter<_true>::value = 0; 

template<> 
struct Counter<false>; // disable the other alternative so no one can invoke it 

template <class T> 
class Singleton 
{ 
public: 
    Singleton(const std::string &name){ 
     printf("%s CTOR call #%d\n", name.c_str(), s_counter.value); 
     s_counter++; 
    } 
    virtual ~Singleton(){} 
private: 
    static Counter<true> s_counter; // shared by all classes 
}; 
template<class T> 
Counter<true> Singleton<T>::s_counter; 
+0

문제는입니다. 값 인스턴스를 두는 곳의 cpp 파일을 제공해야합니다. 나는 그 사실을 극복 할 수 없다고 생각합니다 ... – Gui13

+0

@ Gui13, 아니요,이 스 니펫을 stijn의 솔루션과 결합하여 사용하십시오 ... – Nim

+1

제 설정에서 'unsigned int Counter :: value = 0;'의 인스턴스가 여러 개 있기 때문에 솔루션이 연결되지 않습니다. '내 "Singleton.h"파일을 포함 할 때마다 정의됩니다. 테스트에 참여하는 헤더 파일이 없기 때문에 테스트가 작동합니다. 컴파일하려면, 멤버 함수에'value'를 넣어야합니다. 멤버 함수는 마침내 님의 대체 솔루션으로옵니다. – Gui13

관련 문제