Qual é a maneira correta de inicializar um membro estático do tipo 't &' em uma classe modelada?

StackOverflow https://stackoverflow.com/questions/2089021

Pergunta

Estou brincando com uma aula de singleton genérico que inicializa. A idéia é que você herde publicamente da aula como assim:

class foo : public singleton<foo> { };

Aprendi muito no processo, mas estou preso agora porque está quebrando meu vinculador do Visual Studio 2008. O problema é com o membro da instância estática e/ou sua inicialização.

template<class T>
class singleton {
    singleton();
    singleton(singleton const &);
    singleton & operator = (singleton const &);
public:
    static T & instance;
};
template<class T> T & T::instance;

Qualquer insight seria muito apreciado!

EDITAR:

Com esta declaração de classe ...

template<class T>
class singleton {
    singleton();
    singleton(singleton const &);
    singleton & operator = (singleton const &);
public:
    static T instance;
};
template <class T> T singleton<T>::instance;

Quando tento fazer isso ...

class foo : public singleton<foo> { };

Eu recebo este erro ...

Erro C2248: 'Singleton :: Singleton': Não é possível acessar o membro privado declarado na classe 'Singleton'

...

Esse diagnóstico ocorreu na função gerada pelo compilador 'Foo :: foo (void)'

Minha interpretação é que Singleton quer construir um objeto Foo que, por herança, depende da construção de um singleton cujo construtor é privado. Imaginei que Singleton teria acesso ao seu próprio construtor, mas acho que não. Alguma ideia?

Editar 2:

Eu percebi que a abordagem de herdar singleton<T> Tem o problema de exigir que a mudança para a classe seja usada como um singleton. Acabei com o código a seguir para o meu modelo de aula de singleton que inicializa.

template<typename T>
class singleton_wrapper {
    singleton_wrapper();
    singleton_wrapper(singleton_wrapper const &);
    singleton_wrapper & operator = (singleton_wrapper const &);
    static T instance;
    template<typename T> friend T & singleton();
};
template<typename T> T singleton_wrapper<T>::instance;

template<typename T>
T & singleton() {
    return singleton_wrapper<T>::instance;
}

Para classe...

class foo {
public:
    void bar() { }
};

... Alguém poderia acessar uma única instância (inicializada antes de main ()) usando o seguinte:

singleton<foo>().bar();

Mais uma vez obrigado pela ajuda, especialmente Gman. Estou muito satisfeito com minha primeira experiência na pilhatransbordar.

Foi útil?

Solução

Você não pode, já que não tem uma instância concreta. Você pode precisar criar uma instância real à qual possa se referir:

template <class T>
class singleton {
    ...
private:
    static T instance_;
public:
    static T& instance;
};
template <class T> T singleton<T>::instance_;
template <class T> T& singleton<T>::instance = singleton<T>::instance;

Ou, mais simplesmente, apenas abandone a referência:

template <class T>
class singleton {
    ...
public:
    static T instance;
};
template <class T> T singleton<T>::instance;

Outras dicas

Fora da manutenção: altere a instância para ser do tipo 't' em vez de 't &'.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top