zoukankan      html  css  js  c++  java
  • A template Singleton class

    5年前在学校,写了一篇关于单例设计的Blog,最近需要写3个单例对象,如果每个对象都写一遍单例模式,显得很冗余。所以需要应用单例模板类。

    基于之前的内容:https://www.cnblogs.com/wangpei0522/p/4460529.html 

    很容易扩展为使用模板继承的单例辅助类:

     1 template<typename T>
     2 class Singleton
     3 {
     4 protected:
     5     Singleton()
     6     {
     7         std::cout << "Construct singleton" << std::endl;
     8     }
     9 
    10     virtual ~Singleton()
    11     {
    12         std::cout << "Destruct singleton" << std::endl;
    13     }
    14 
    15 public:
    16     static T& GetInstance()
    17     {
    18         if (!m_instance_) m_instance_ = new T{};
    19         static auto* ptr = &m_helper_; // To 读者, 尝试注释运行一遍
    20         return *m_instance_;
    21     }
    22 
    23 private:
    24     static T* m_instance_;
    25 
    26 private:
    27     class Helper
    28     {
    29     public:
    30         Helper()
    31         {
    32             std::cout << "Help construction " << std::endl;
    33             GetInstance();
    34         }
    35 
    36         ~Helper()
    37         {
    38             std::cout << "Help destruction " << std::endl;
    39 
    40             if (Singleton<T>::m_instance_)
    41             {
    42                 delete Singleton<T>::m_instance_;
    43                 Singleton<T>::m_instance_ = nullptr;
    44             }
    45         }
    46     };
    47 
    48     static Helper m_helper_;
    49 };
    50 
    51 template<typename T>
    52 T* Singleton<T>::m_instance_ = nullptr;
    53 
    54 template<typename T>
    55 typename Singleton<T>::Helper Singleton<T>::m_helper_;


    写出这个类并不难。但在第一版中,没有第19行。

    如果你注释掉第19行,测试很容易发现:

     1 class A : public Singleton<A>
     2 {
     3     friend class Singleton<A>;
     4 
     5     A()
     6     {
     7         std::cout << "Construct A" << std::endl;
     8     }
     9 
    10     ~A()
    11     {
    12         std::cout << "Destruct A" << std::endl;
    13     }
    14 
    15     A& operator=(const A&) = delete;
    16 
    17 public:
    18     void Print()
    19     {
    20         std::cout << "A's Print function " << std::endl;
    21     }
    22 };
    23 
    24 int main()
    25 {
    26     A& a = A::GetInstance();
    27 
    28     a.Print();
    29 
    30     return 0;
    31 }

    打印的结果是:

    Construct singleton
    Construct A
    A's Print function

    显然the static member of a template class does not be initialized

    typename Singleton<T>::Helper Singleton<T>::m_helper_;

    找了几篇资料发现,static member是按需初始化. 

    https://stackoverflow.com/a/6959729

    "In a class template, when performing implicit instantiation, the members are instantiated on demand. Since the code does not use the static member, it is not even instantiated in the whole application"

    那么一切都很清晰了,也符合模板实例化的原则。 加入第19行的代码:

    static auto* ptr = &m_helper_;

    得到符合预期的结果:

    Help construction
    Construct singleton
    Construct A
    A's Print function
    Help destruction
    Destruct A
    Destruct singleton
  • 相关阅读:
    CF做题记录
    MobaXterm左侧没有文件列表,没有SCP,不显示文件夹问题处理
    使用FastJson转换Object时,空字符串丢失的解决办法【转】
    fastjson处理复杂对象,参数为null问题定位
    python 数据库连接池
    Git找回add 后,未commit的文件(使用reset -hard 命令导致文件清除)
    nginx过滤来自特定IP和user-agent的请求
    Redis实现排行榜(带二位小数点)
    系统不做任何优化,性能提升10%的方法
    二(二)、基于注解形式配置bean
  • 原文地址:https://www.cnblogs.com/wangpei0522/p/13043915.html
Copyright © 2011-2022 走看看