2010-12-16 5 views
0

я должен два класса,Базовый класс шаблонный в C++

class CFoo 
{ 
    public: 
     static CFoo& GetInstance() 
     { 
     static CFoo instance; 
     return instance; 
     } 

     int GetValue(){ 
     return value; 
     } 

    private: 
     CFoo(){ 
     value = 0; 
     ltr = 'a'; 
     } 

     int value; 
     char ltr; 
}; 

class CBar 
{ 
    public: 
     static CBar& GetInstance(){ 
     static CBar instance; 
     return instance; 
     } 

     float GetValue(){ 
     return value; 
     } 

    private: 
     CBar(){ 
     value = 0.4; 
     ltr = 2; 
     } 

     float value; 
     int ltr; 
}; 

Можно просто создать шаблон класса для этого два класса, разница только типы данных. И так как класс является singleton, как я могу вызвать, когда создаю класс шаблона для этого двух классов? И, пожалуйста, дайте пример кода для базового класса шаблона.

Прошу совета.

Большое спасибо.

+1

Это странная реализация singleton, которая возвращает новый экземпляр при каждом вызове `GetInstance()`. – 2010-12-16 03:51:31

+0

@Fred Larson, объект экземпляра является статическим, поэтому в основном он не будет создан, если экземпляр еще не уничтожен. – domlao 2010-12-16 03:54:00

ответ

6

Как правило, если вы хотите обобщить аналогичные классы, подобные этому, вы можете сделать это, заменив каждый из типов параметрами типа. Так, например, здесь вы должны объявить параметр типа для типа value и параметр типа для типа ltr.

Это, очевидно, выглядит примерно так:

template <typename ValueT, LtrT> 
class C 
{ 
    // ... 
}; 

Тогда это просто вопрос замены конкретных типов в классе с параметрами типа, так value и ltr будет объявлен (внутри класса определение шаблона):

ValueT value; 
LtrT ltr; 

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

typedef C<int, char> CFoo; 
typedef C<float, int> CBar; 

Вам также нужен способ инициализации переменных-членов. Лучше всего, чтобы сделать конструктор принять аргументы для инициализации переменных-членов (внутри определения шаблона класса):

C(const ValueT& initial_value, const LtrT& initial_ltr) 
    : value(initial_value), ltr(initial_ltr) { } 

Поскольку вы пытаетесь использовать синглтон, это не будет работать с током (сломанной) реализации GetInstance(), потому что static-static-функция должна быть инициализирована в теле функции. Вы можете обойти эту проблему, объявив одноэлементный экземпляр в качестве переменного статического члена класса (внутри определения шаблона класса):

C singleton; 

, то вам необходимо будет определить и инициализировать это в одном из исходных файлов; вам нужно будет иметь одно определение для каждого экземпляра C, который вы используете, поэтому для двух вы здесь вам потребуется:

template<> CFoo CFoo::singleton(0, 'a'); 
template<> CBar CBar::singleton(0.4, 2); 

Когда вы все это вместе, это будет выглядеть примерно так (I» ве упрощенных его вниз, чтобы использовать только один тип и значение для краткости):

template <typename T> 
struct S 
{ 
public: 
    S(const T& initial_value) : value(initial_value) { } 

    const T& GetValue() const { return value; } 

    static const S& GetInstance() { return singleton; } 

private: 
    // since it's a singleton, make it noncopyable 
    S(const S&); 
    void operator=(S); 

    T value; 
    static S singleton; 
}; 

typedef S<int> SInt; 

template<> SInt SInt::singleton(42); 

int main() 
{ 
    int value = SInt::GetInstance().GetValue(); 
} 

и наконец, самое главное, почему бы не использовать синглтона. Синглтоны почти всегда являются плохими идеями. Невозможно сказать, что вы пытаетесь выполнить из вашего урезанного примера, но вам обязательно нужно попытаться найти другой способ сделать это.

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