C++单例模式的理解及使用

1. 为什么要单例模式?

        在对象需要获取全局变量时,我们需要用到单例模式,单例模式也是解决获取全局变量的重要方法之一。

2. 单 例模式的原理

        单例模式,通过私有化构造函数来达到不给外界实例化对象,之后再由该对象提供一个静态公有接口创建这个对象,该接口并对该对象是否已创建判断,再取决是否创建对象,达到一个全局唯一的效果。之后就通过该接口就可以对该对象的类内公有成员进行访问了。

3.简单实现

#include <iostream>

using namespace std;

class A
{  
private:  
    a();   //构造函数是私有的,这样就不能在其它地方创建该实例
    static A *p;  //定义一个唯一指向实例的静态指针,并且是私有的。
    static int b;
public:  
    static A* instance() //定义一个公有函数,可以获取这个唯一的实例,并且在需要时创建该实例。
    { 
        if(p == NULL)  //判断是否第一次调用  
            p = new A;  
        return p;  
    }  
    static void show()
	{
		cout << b << endl;
	}
}; 

int A::b=1;  //static定义的数据成员必须在类外初始化,因为它是整个类的一部分,而不是属于某个对象。
only* A::p=NULL;

说明:

        可以看出,实现一个简单的单例模式,主要分为三个步骤:

        1.私有化构造函数,使其不可以没直接被外部实例化。

        2.在其类内公有成员区做一个创建类的方法。

        其本质是外部由于不可访问类的私有区,所以通过类自己的公有去访问创建私有区的构造函数,从而创建类。之后对该方法做全局唯一的限制,就可以保证全局只创建一次对象。

        3.类外部定义指向该对象的指针。

4.饿汉单例模式

//  单例类
class A {
public:
    //  获取此类的 唯一静态实例
    static A & getInstance() {
        return instance;
    }
    //  公有函数部分
    void func1() {
        cout << "1" << endl;
    }
private:
    //  私有化 默认构造函数 拷贝构造函数 析构函数
    //  即 禁止对 class singleton 的类外构造和拷贝
    A() {
        //  构造部分
    };
    A(A &b) {
        //  此函数无用 因为已经私有化
        //  相当于禁止了拷贝构造
    };
    ~A() {
        //  析构部分
    };
	static A instance;
};
//使用方法
int main(int argc, char *argv[]) {
    //  由于私有化了 默认构造函数 以及 拷贝构造函数
    //  所以只可以用引用方式 获取到单例类的实例
    A &c = A::getInstance();
    
    A.func1();

    system("pause");
    return 0;
}

        饿汉模型通过static在程序刚刚开始执行的时候就对对象进行实例化了。这样做的结果是更快的初始化对象,缺点是资源浪费。

5.懒汉模式

class A
{  
private:  
    static A* m_instance;  
    A(){}  
public:  
    static A* getInstance();  
};  
  
A* A::getInstance()  
{  
    if(NULL == m_instance)  
    {  
        Lock();//借用其它类来实现,如boost  
        if(NULL == m_instance)  
        {  
            m_instance = new Singleton;  
        }  
        UnLock();  
    }  
    return m_instance;  
} 

懒汉模式写法如下,只有在使用的时候才实例化对象。缺点就是慢。

这里使用一个完整的例子。

class sun :public son
{
public:
	~sun() {std::cout << "sun::~sun()";}
public:
	static sun * GetInstance();
private:
	sun(int a, int b, int c, double m, int d);
	static sun * m_instance;
};
#include"instance.h"
sun * sun::m_instance(NULL);

sun::sun(int a, int b, int c, double m, int d) :son(a, b, c, m, d)
{
	std::cout << "sun::sun"<<endl;
}
sun * sun::GetInstance()
{
	if (NULL == m_instance)
	{
		m_instance = new sun(5,6,7,8.2,10);
	}
	return m_instance;
}
//然后主函数如下:
#include"instance.h"
//#include"instancetest.h"
using namespace::std;
int main()
{
	sun * test = sun::GetInstance();
	return 0;
}

*本文为学习笔记,如有不对,或有高见的欢迎留言。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值