2010-01-18 4 views
4

Я играю с нетерпеливым инициализирующим общим классом одноэлементного. Идея заключается в том, что вы унаследовали публично от класса, как так:Каков правильный способ инициализации статического члена типа «T &» в шаблоном?

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 (ничтожной)»

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

EDIT 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() { } 
}; 

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

singleton<foo>().bar(); 

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

+1

Я недавно решил (\ * кашель \ * jalf \ * cough \ *), чтобы советовать не создавать одноэлементный класс. Глобальные переменные работают нормально, без ограничений. Для учебного упражнения, пожалуйста, продолжайте! Но я убежден, что они никогда не нужны. – GManNickG

+0

Предполагается, что синглеты должны решить проблему неопределенного iconstruction-order (т. Е. Вы не можете быть уверены в том, какие глобальные глобальные объекты построены, поэтому один глобальный объект, который использует другой, не может быть уверен, что объект, который он использует, инициализируется), а также принудительно что существует только один экземпляр. (Нет ничего, что помешает вам объявить еще один глобальный.) –

+0

@Mike: Мне хорошо знакомы статические проблемы с инициализацией. Глобальная функция имеет тот же эффект без беспорядка. Когда вы когда-либо * требовали *, класс не был создан более одного раза? – GManNickG

ответ

7

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

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; 
+0

Не могли бы вы улучшить свой ответ? На какой вопрос вы не можете ответить? – HelloGoodbye

1

Внебиржевой вариант: заменить экземпляр типа «T» вместо «T &».

Смежные вопросы