单例模式之C++实现
来源:互联网 发布:解压缩软件64位 编辑:程序博客网 时间:2024/06/06 08:25
在软件开发中,有些资源通常只要生成一份,为了避免在程序中其他地方生成另外一份,或者生成另一份新的拷贝,必须在编码的时候利用语言编程技术来保证只会产生一份资源,而这样的编程技术称之为单例模式
根据单例的特点可以知道用C++来实现需要考虑的要点:
- 使得对象不能被拷贝、赋值;
- 所有的构造函数必须私有(这样就不会让 A a; A *p = new A; 通过编译);
- 但要保证在某处生成一个这样的对象;
第一条实现方式是通过把拷贝构造、拷贝赋值函数设为private类型;第二条实现方式跟第一条一样既把构造函数设为private类型;第三条貌似与第二条产生了冲突,确实如此,但可以通过友元的方式来实现。
首先来写一个Uncopyable类,大致如下:
class Uncopyable { protected: Uncopyable(){} ~Uncopyable(){} private: /* * 以下都只给出声明,这样的话如果在Uncopyable的成员函数或者是友元函数或类中方式拷 * 贝,则编译器在链接阶段会因为找不到定义而报错,同样阻止了这一类比较特别拷贝赋值操 * 作,当然这里主要是阻止 A a(b), A a=b,a=b 这种情况的发生(A是Uncopyable的派生类) */ Uncopyable(const Uncopyable&); const Uncopyable& operator=(const Uncopyable&);}
接着来写一个单例的模板父类:
tempalte<class T>class Singleton { public: static T * getInstance() { static T instance; return &instance; }}
然后写一个用例,假设一个类A我只让它产生一个对象:
#include <iostream>using namespace std;class A: public Uncopyable { friend class Singleton<A>;//使得类Singleton中可以调用所有A的私有构造函数 private: A(){} ... // 其他类型的构造函数};int main(){ A * a_ptr = Singleton<A>::getInstance(); cout << ( a_ptr == Singleton<A>::getInstance())<<endl; //编译通过,结果为1,也就是同一个指针 A b; //编译报错,提示A的构造函数私有 A c(*a_ptr);//编译错误,提示Uncopyable的拷贝构造函数是私有的 A d = *a_ptr;//同上,因为声明赋值同样是调用的拷贝构造函数 *a_ptr = *Singleton<A>::getInstance();//编译错误,提示operator=拷贝赋值函数为私有的 return 0;}
以上都是c++11环境下编译验证;
虽然上面的单例模式确实做到了基本功能,但是还是有些问题:
1. 返回指针容易使得程序猿无意识的 delete
这个指针;
2. 多线程不是安全;
先来看看解决1的一个方案:
把Singleton::getInstance 返回指针变成返回引用
... static T & getInstance(){ static T instance; return instance; } ...
在获取实例时则这么写:
... A &a = Singleton<A>::getInstance();//这样的话应该没有程序猿会写 delete a这样的操作了把,即使写了,编译器也会提前告诉你 ...
第2个多线程问题,就是单例中的懒汉与饿汗两种模式了。说下大致思路把,饿汗了就是在程序启动阶段就初始化一个A的对象,以后不管多个线程直接取就是了,懒汉了当地第一次使用getInstance()才初始化一个A的对象,以后每次都是取第一次初始化的那个A对象。从这里就可以看出前面举的例子就是懒汉模式,懒汉模式的解决方法一般采用加锁的形式避免多线程竞争,而饿汗模式就不用考虑多线程问题。
下面来把上面的改成饿汗模式:
新加一个饿汗模式的单例类
template<class T>class SingletonEager{ public: static T * getInstance(){ return instance; } private: static T * instance;}template<class T>T * SingletonEager<T>::instance = new T;
而我们的类A也只需要改成如下即可:
class A:public Uncopyable{ friend class SingletonEager<A>; private: A(){} ... //其他类型的构造函数}
其他情况请读者思考吧, 如有问题请大家指正……
1 0
- 【C++】单例模式之C++实现
- objective-C之宏定义实现单例设计模式
- 设计模式--单例模式 C++实现
- C++--模式之单例模式
- (C#)设计模式 之 单例模式
- 设计模式之单例模式(C++)
- C#--设计模式之单例模式
- Objective C 中实现单例模式
- Objective C 实现Singleton(单例)模式.
- Objective-C实现单例模式
- 【Objective-C】单例模式的实现
- objective-C 实现单例模式
- 单例模式代码实现(C++)
- 单例模式 (C语言实现)
- Objective-C实现单例模式
- Objective-C单例模式实现
- Objective-C 单例模式的实现
- Objective-c 实现单例设计模式
- 通过CAGradientLayer制作渐变色效果【原创】
- Poj3299 Humidex java 分析
- Android Binder机制(超级详尽)
- Java进阶(二十四)Java List集合add与set方法原理简介
- 蘑菇街 App 的组件化之路·续
- 单例模式之C++实现
- JAVA开发面试笔记
- 1. 数据结构 - 复杂度分析
- 为什么不能把构造函数声明为虚函数
- 设计模式:Web App 系统架构(一)
- 超出系统启动限定个数-----系统运维日志30
- java获取数据中N个最大值的方法
- java.lang.UnsatisfiedLinkError: Couldn't load hyphenate from loader dalvik.system.
- UITabbarController