arunz

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

单例模式也称为单件模式、单子模式,可能是使用最广泛的设计模式,主要分为饿汉式和懒汉式,网上有许多资料。

blog.jobbole.com/108579

http://blog.csdn.net/woxiaohahaa/article/details/51344409

这里重点提几个需要注意的问题:

1.构造函数私有化

为了避免用户在任意地方生成实例


 

2.线程安全

线程安全问题只存在懒汉式单例模式中,主要是在GetInstance()中new对象之前使用锁,双检锁,局部变量过渡等方法实现线程安全,参考https://www.cnblogs.com/myd620/p/6133420.html


 

3.实例析构的时间点

实例为静态对象,在程序结束时析构;

但是资料上这么说“如果在类的析构行为中有必须的操作,比如关闭文件,释放外部资源(设断点调试了一下,确实没有进入singleton的析构函数),那么上面的代码无法实现这个要求。我们需要一种方法,正常的删除该实例”

(1)常规做法是在单例类里定义私有内嵌类CGarbo的静态私有对象Garbo,在私有内嵌类实现单例实例的析构。需要注意的是该私有内嵌类没有数据,因此该静态私有对象需要在类外部进行初始化,否者虽然编译不报错,但是该对象不会生成,则该对象相当于没有,参考https://yq.aliyun.com/wenzhang/show_70374

(2)另一种做法是声明实例的对象为getinstance()的静态局部变量,但需要考虑复制函数等,即:

class Singleton {
public:
  static Singleton& getInstance(){
    static Singleton instance;
    return instance;
  }
};

个人不太喜欢这种方法,但知乎上有人说这种方法是C++11标准单例类

 (3)也可以直接用智能指针管理实例;

参考http://blog.csdn.net/realxie/article/details/7090493;


 

4.单例模式模板化(没有搜到认为太好的模板单例类资料,贴一个参考http://blog.csdn.net/kentzhang_/article/details/48206821)

为了实现程序复用,将单例类抽象成单例模板类。FreeNOS源码中也有单例模板类,但是里面过于简单,不推荐。需注意问题:

(1)基础知识点:模板类的类方法的定义和声明需要在同一个.h文件中,不能分开。详见c++primer plus

(2)作为模板类型的类的构造函数,析构函数设置为私有。

(3)在需要使用单例类模式的类中,用友元关键friend + class + 单例类模板的名字<当前类的名字>,将单例类模板声明为当前类的友元:

  template<typename T>
  friend class MySingleton;

(4)第3点析构问题的(1)用在模板类上,会出现一个问题:模板类的私有内嵌类CGarbo的内嵌静态私有对象Garbo的初始化问题,

若在外部初始化为

template<typename T>
MySingleton<T>::CGarbo MySingleton<T>::Garbo;

会出现如下错误:

error C2143: syntax error : missing ';' before 'MySingleton<T>::Garbo'

error C4430: missing type specifier - int assumed. Note: C++ does not support default-int

fatal error C1903: unable to recover from previous error(s); stopping compilation

伪解决方法:

template<typename T> typename 
MySingleton<T>::CGarbo MySingleton<T>::Garbo;

参考http://ask.csdn.net/questions/222830

添加typename只是编译通过了,但是并没有真正初始化,如3.(1)中所说该对象相当于没有。

我当前做法是使用具体初始化:

在testClass类的testClass.h文件的类外面初始化

MySingleton<testClass>::CGarbo MySingleton<testClass>::Garbo;

真正解决方法还没找到

 

总结(2).(3).(4)点,模板类型的testClass类,设计如下所示:

#include "MySingleton.h"
class testClass
{
private:
testClass(void);
~testClass(void);

private:
template<typename T>
friend class MySingleton;
};
MySingleton<testClass>::CGarbo MySingleton<testClass>::Garbo;


 

 

 

 

 

转载请注明出处

posted on 2017-12-29 11:37  arunz  阅读(222)  评论(0)    收藏  举报