C ++中的基本类模板

时间:2010-12-16 03:39:39

标签: 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;
};

是否可以为这两个类创建一个类模板,区别仅在于数据类型。由于该类是单例,我在为这两个类创建模板类时如何调用?请提供基本模板类的示例代码。

请建议。

非常感谢。

1 个答案:

答案 0 :(得分:6)

通常,当您想要概括类似这样的类时,可以通过用类型参数替换每个类型来实现。因此,例如,您可以在此处为value类型声明类型参数,并为ltr类型声明类型参数。

这显然看起来像:

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

然后,只需要使用类型参数替换类中的具体类型,因此valueltr将被声明为(在类模板定义中):

ValueT value;
LtrT ltr;

为了使这个类模板更容易使用,你可以创建一些typedef(在类模板定义之外):

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()的当前(损坏)实现,因为函数体静态需要在函数体中初始化。您可以通过将单例实例声明为静态类成员变量(在类模板定义内)来解决此问题:

C singleton;

然后你需要在你的一个源文件中定义和初始化它;您将需要为您使用的C的每个实例化定义一个定义,因此对于您需要的两个实例,您需要:

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

当你把它们放在一起时,它会看起来像这样(为了简洁起见,我把它简化为只使用一种类型和值):

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

最后,最重要的是,请考虑不使用单身。单身几乎总是一个坏主意。从你的剥离示例中无法分辨出你想要完成什么,但你一定要尝试找到其他方法来实现它。