• 单例模式


    一、单例模式的析构函数

    不要在单例模式的析构函数中释放单例

    二、单例模式懒汉式和饿汉式的区别

    1. 实例化:

    懒汉式默认不会实例化,外部什么时候调用什么时候new。饿汉式在类加载的时候就实例化,并且创建单例对象。

    2. 线程安全:

    饿汉式线程安全,在线程还没出现之前就已经实例化了,因此饿汉式线程一定是安全的。

    懒汉式线程不安全,因为懒汉式的是在使用时才会实例化,如果此时有多个线程都需要实例化,都进入了new方法,就会不知道到底需要返回哪一个实例,(加同步锁可以解决该问题)

    3. 效率:

    因为懒汉式一般需要加锁,所以在效率上懒汉式的效率更低

    4. 性能

    饿汉式无论是否使用,都会在类加载的时候实例化,因此更占用空间,浪费内存。

    三、C++11之后单例模式的实现

    std::call_once

    四、单例模式的单例对象(创建,初始化,销毁,static)

    static

    五、两次判空

    只有懒汉式才会出现这种情况,饿汉式不需要加锁

    Singleton* getInstance()
    {
        lock();
        if (instance == NULL)
        {
           instance = new Singleton();
        }
        unlock();
        return instance;
    }
    

    因为每次判断是否为空都需要被锁定,如果有很多线程的话,就会造成大量线程的阻塞,所有就有了两层锁。

    Singleton* getInstance()
    {
        if (instance == NULL)
        { //只有为空的线程才会进入锁,这样可以避免很多不为空的线程进入,不会阻塞很多线程
    	lock();
        	if (instance == NULL)
        	{
           		instance = new Singleton();
        	}
        	unlock();
        }
        return instance;
    }
    

    完整代码

    单例模式
    #include <iostream>
    using namespace std;
    
    class A
    {
    public:
    	static A* getSingleTon()
    	{
    		//static A* m_p = NULL;  //这样写每次获取单例都会调用构造函数,不建议
    		if (NULL == m_p)
    		{
    			m_p = new A();
    		}
    		return m_p;
    	}
    	///< 释放空间
    	void destroy()
    	{
    		if (m_p)
    		{
    			///< 注意多线程释放
    			delete m_p;
    			m_p = nullptr;
    		}
    	}
    private:
    	static A* m_p;  //此处声明须在类外定义
    	A() { std::cout << "构造
    "; }
    	~A() { std::cout << "析构
    "; }
    
    	//不要在析构函数中释放
    	//~A()
    	//{
    	//    if (NULL != m_p)
    	//    {
    	//        cout << "xxx" << endl;
    	//        delete m_p; // 递归调用析构
    	//        m_p = NULL;
    	//        cout << "yyy" << endl; // 永远也不会执行
    	//    }
    	//}
    };
    
    A* A::m_p = nullptr;
    
    int main()
    {
    
    	A* p = A::getSingleTon();
    	p->destroy();
    
    	return 0;
    }
    
  • 相关阅读:
    Html-浅谈如何正确给table加边框
    如何在移动设备上调试html5开发的网页
    swiper嵌套小demo(移动端触摸滑动插件)
    移动端如何用swiper实现导航栏效果
    background-color:transparent
    点击按钮 发送短信验证码后60秒倒计时
    placeholder的样式设置
    linux 定时任务crontab
    laravel学习一
    centos 7安装jdk
  • 原文地址:https://www.cnblogs.com/mmmmmmmmm/p/15346756.html
Copyright © 2020-2023  润新知