Как правильно инициализировать статический член типа 'T &' в шаблонном классе? - PullRequest
4 голосов
/ 18 января 2010

Я играю с инициализирующим синглтон-классом. Идея в том, что вы наследуете от класса вот так:

class foo : public singleton<foo> { };

Я многому научился в процессе, но сейчас застрял, потому что он ломает мой компоновщик Visual Studio 2008. Проблема в члене статического экземпляра и / или его инициализации.

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

Любое понимание будет с благодарностью!

EDIT:

С этим объявлением класса ...

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

Когда я пытаюсь это сделать ...

class foo : public singleton<foo> { };

Я получаю эту ошибку ...

ошибка C2248: 'singleton :: singleton' : не может получить доступ к приватному члену объявлен в классе «синглтон»

...

Эта диагностика произошла в сгенерированной компилятором функции 'foo :: foo (void)'

Моя интерпретация состоит в том, что синглтон хочет создать объект foo, который по наследству зависит от конструкции синглтона, конструктор которого является закрытым. Я полагал, что синглтон будет иметь доступ к своему собственному конструктору, но я думаю, что нет. Есть идеи?

РЕДАКТИРОВАТЬ 2:

Я понял, что подход наследования от singleton<T> имеет проблему, требующую изменения класса, который будет использоваться в качестве одиночного. Я закончил со следующим кодом для моего нетерпеливо инициализирующего шаблона синглтон-класса.

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;
}

Для класса ...

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

... Можно получить доступ к одному его экземпляру (инициализированному перед main ()), используя следующее:

singleton<foo>().bar();

Еще раз спасибо за помощь, особенно GMan. Я очень доволен своим первым опытом в стеке переполнение .

Ответы [ 2 ]

7 голосов
/ 18 января 2010

Вы не можете, так как у вас нет конкретного экземпляра. Вам может понадобиться создать фактический экземпляр, к которому вы можете обратиться:

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;

Или, проще говоря, просто отбросьте ссылку полностью:

template <class T>
class singleton {
    ...
public:
    static T instance;
};
template <class T> T singleton<T>::instance;
1 голос
/ 18 января 2010

Вне рукава: измените экземпляр на тип 'T' вместо 'T &'.

...