Как правило, если вы хотите обобщить аналогичные классы, подобные этому, вы можете сделать это, заменив каждый из типов параметрами типа. Так, например, здесь вы должны объявить параметр типа для типа 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();
}
и наконец, самое главное, почему бы не использовать синглтона. Синглтоны почти всегда являются плохими идеями. Невозможно сказать, что вы пытаетесь выполнить из вашего урезанного примера, но вам обязательно нужно попытаться найти другой способ сделать это.
Это странная реализация singleton, которая возвращает новый экземпляр при каждом вызове `GetInstance()`. – 2010-12-16 03:51:31
@Fred Larson, объект экземпляра является статическим, поэтому в основном он не будет создан, если экземпляр еще не уничтожен. – domlao 2010-12-16 03:54:00