C++ C+中的基本类模板+;

C++ C+中的基本类模板+;,c++,C++,我要上两节课 class CFoo { public: static CFoo& GetInstance() { static CFoo instance; return instance; } int GetValue(){ return value; } private: CFoo(){ value = 0;

我要上两节课

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;
};
是否可以为这两个类创建一个类模板,区别只是数据类型。既然这个类是一个单例类,那么当我为这两个类创建一个模板类时,如何调用它呢?请给出基本模板类的示例代码

请给我一些建议


非常感谢。

通常,当您想要像这样泛化类似的类时,您可以用类型参数替换每个类型。因此,例如,这里您将为
value
类型声明一个类型参数,并为
ltr
类型声明一个类型参数

显然,这看起来像:

template <typename ValueT, LtrT>
class C
{
    // ...
};
为了使该类模板更易于使用,您可以创建一些typedef(在类模板定义之外):

由于您正在尝试使用单例,因此这对当前的
GetInstance()
实现(已损坏)不起作用,因为函数范围静态需要在函数体中初始化。您可以通过将singleton实例声明为静态类成员变量(在类模板定义内)来解决此问题:

然后您需要在一个源文件中定义并初始化它;对于所使用的
C
的每个实例化,您需要有一个定义,因此对于这里的两个实例,您需要:

template<> CFoo CFoo::singleton(0, 'a');
template<> CBar CBar::singleton(0.4, 2);
template CFoo CFoo::singleton(0,'a');
模板CBar-CBar::singleton(0.4,2);
当你把它放在一起时,它看起来是这样的(为了简洁起见,我简化了它,只使用一个类型和值):

模板
结构
{
公众:
S(常数T和初始值):值(初始值){}
常量T&GetValue()常量{返回值;}
静态常量S&GetInstance(){return singleton;}
私人:
//既然它是单身,就让它不可复制
S(常数S&);
void运算符=(S);
T值;
静态S单态;
};
S型烧结;
模板烧结:单体(42);
int main()
{
int value=SInt::GetInstance().GetValue();
}

最后,最重要的是,<强>请考虑不要使用单点< /强>。单身几乎总是个坏主意。从简化的示例中不可能看出您想要实现什么,但您肯定应该尝试找到其他方法来实现它。

通常,当您想要像这样泛化类似的类时,可以通过用类型参数替换每个类型来实现。因此,例如,这里您将为
value
类型声明一个类型参数,并为
ltr
类型声明一个类型参数

显然,这看起来像:

template <typename ValueT, LtrT>
class C
{
    // ...
};
为了使该类模板更易于使用,您可以创建一些typedef(在类模板定义之外):

由于您正在尝试使用单例,因此这对当前的
GetInstance()
实现(已损坏)不起作用,因为函数范围静态需要在函数体中初始化。您可以通过将singleton实例声明为静态类成员变量(在类模板定义内)来解决此问题:

然后您需要在一个源文件中定义并初始化它;对于所使用的
C
的每个实例化,您需要有一个定义,因此对于这里的两个实例,您需要:

template<> CFoo CFoo::singleton(0, 'a');
template<> CBar CBar::singleton(0.4, 2);
template CFoo CFoo::singleton(0,'a');
模板CBar-CBar::singleton(0.4,2);
当你把它放在一起时,它看起来是这样的(为了简洁起见,我简化了它,只使用一个类型和值):

模板
结构
{
公众:
S(常数T和初始值):值(初始值){}
常量T&GetValue()常量{返回值;}
静态常量S&GetInstance(){return singleton;}
私人:
//既然它是单身,就让它不可复制
S(常数S&);
void运算符=(S);
T值;
静态S单态;
};
S型烧结;
模板烧结:单体(42);
int main()
{
int value=SInt::GetInstance().GetValue();
}

最后,最重要的是,<强>请考虑不要使用单点< /强>。单身几乎总是个坏主意。从精简的示例中不可能看出您想要实现什么,但您肯定应该尝试找到其他方法。

这是一个奇怪的单例实现,每次调用
GetInstance()
@Fred Larson时都会返回一个新实例,实例对象是静态的,因此如果实例尚未销毁,它基本上不会创建。但您是按值返回它,因此每次调用都会返回一个副本。这段代码毫无意义。它有什么好处?如果你揭示了真正的代码,或者至少是它的相关部分,以及更多的上下文,那么你就会得到一个相关的答案。你知道,如果有人告诉你你问错了问题,那是件好事。为什么要降低反馈的质量?@Fred Larson,哎呀,这应该是一个参考。这是一个奇怪的单例实现,每次调用
GetInstance()
@Fred Larson时都会返回一个新实例,实例对象是静态的,因此如果实例尚未销毁,它基本上不会创建。但您是按值返回它,因此每次调用都会返回一个副本。这段代码毫无意义。它有什么好处?如果你揭示了真正的代码,或者至少是它的相关部分,以及更多的上下文,那么你就会得到一个相关的答案。你知道,如果有人告诉你你问错了问题,那是件好事。为什么会降低反馈的质量?@Fred Larson,oops,它应该是一个引用。由于它是一个单例,如何调用这个模板类或创建的实例?初始化成员变量如何?@sje397:oops;我没看到。哎呀,怎么调用这个t
C singleton;
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(); 
}