首页 > 编程语言 >C++设计模式:单例模式

C++设计模式:单例模式

时间:2023-06-05 17:11:36浏览次数:44  
标签:设计模式 getInstance C++ Single 线程 单例 static include

什么是单例模式?
单例模式指在整个系统生命周期里,保证一个类只能产生一个实例,确保该类的唯一性。

单例模式分类有哪些?
单例模式可以分为懒汉式和饿汉式,两者之间的区别在于创建实例的时间不同:
懒汉式:指系统运行中,实例并不存在,只有当需要使用该实例时,才会去创建并使用实例。(这种方式要考虑线程安全)
饿汉式:指系统一运行,就初始化创建实例,当需要时,直接调用即可。(本身就线程安全,没有多线程的问题)

懒汉实现:

class Single
{
    private:
       Single() {}
       static Single *p;

    public:
       static Single *getInstance();
};

Single *Single::p = NULL;

Single *Single::getInstance()
{
    if (p == NULL)
    {
        p = new Single();
    }
    return p;
}

饿汉实现:

class Single
{
    private:
       Single() {}
       static Single *p;

    public:
       static Single *getInstance();
};

Single *Single::p = new Single();

Single *Single::getInstance()
{
    return p;
}

多线程双重锁定的单例模式:
(1) 当两个或两个以上的线程同时执行GetInstance的时候,肯定有一个线程拿到锁并把单例对象创建好了,故这个首线程退出后,其它的线程再进入也无法再创建新的对象了
(2) 存在的问题是首线程之外的线程明明没有了创建对象的权利还天天的去拿锁,造成资源的浪费。
为解决上述问题引入双重锁定,如下:
所谓的双重锁定只不过是在上锁之前也进行一下检查,如果说你连拿到锁的资格都没有你凭啥去创建对象。

#include <iostream>
#include <stdio.h>
#include <pthread.h>
#include <thread>
#include <mutex>
#include <cstdlib>
using namespace std;

mutex mtx;
#define NUM 5
class Single
{
    public:
        static Single *getInstance();
         
        void Print()
        {
            if(m_Single == NULL)
            {
                printf("m_Single is NULL!\n");
            }
            cout<<this<<" 刘亦菲 是一个美人!"<<endl;
        }
        Single()
        {
            printf("Single()\n");
        }
        ~Single()
        {
            printf("~Single()\n");
        }
        
    private: 
        Single(const Single &signal);
        Single &operator=(const Single &signal);
        
        static Single *m_Single;
        
};

Single *Single::m_Single = NULL;
Single* Single::getInstance()
{
    if (m_Single == NULL)
    {
        mtx.lock();
        if (m_Single == NULL)
        {
            m_Single = new Single;
            mtx.unlock();
            return m_Single;
        }
    }
    mtx.unlock();
    return m_Single;
}
void threadFun()
{
    printf("我的线程开始执行了!\n");
    Single *sig = Single::getInstance();
    sig->Print();
    printf("我的线程结束了!\n");
}
int main()
{
    thread thd1,thd2;
    thd1 = thread(threadFun);
    thd2 = thread(threadFun);
    thd1.join();
    thd2.join();
    return 0;
}

 

标签:设计模式,getInstance,C++,Single,线程,单例,static,include
From: https://www.cnblogs.com/lyfily-p-7439305/p/17458306.html

相关文章

  • C++ 子类调用父类的方法,静态方法的调用
    #include<iostream>classA{public:A();~A();virtualvoidsay(){std::cout<<"HellothisisclassA!\n";}staticvoidtest(){std::cout<<"HellothisisclassAtestfunction..!\n";}private:};......
  • c++ 与c#之间的字符串传递
    1.方法中不要直接返回字符串,防止内存崩溃。c++写法:voidnecall(char*str1,char*outdata){strcpy(outdata,str1);}outdata为导出数c#写法:[DllImport("testdemo")]privatestaticexternvoidnecall(stringa,StringBuilderb);StringBuilderb=new......
  • C#设计模式19——装饰器模式的写法
    装饰器模式(DecoratorPattern)是一种结构型设计模式,它允许你动态地给一个对象添加一些额外的职责,而不需要修改这个对象的代码。What(什么)装饰器模式是一种结构型设计模式,它允许你动态地给一个对象添加一些额外的职责,而不需要修改这个对象的代码。在装饰器模式中,你可以定义一个装......
  • 利用PImpl在C++14中优雅调用C++17方法
    诉求你的工程由C++14写成,某天你看中了一个功能强大的三方库,一切都好除了该库仅支持C++17编译,对于比较复杂的三方库使用C++14进行重构工作量太大,有没有优雅的办法?实现历史总是惊人的相似,为了解决这一问题前人发明了PImpl编程方法用于隐藏class的实现细节,头文件中仅声明抽象class......
  • C++-语法复习
    记录一些刷算法题中的常用C++语法。STL相关向量Vector头文件:#include<vector>初始化:vector<数据类型>变量名(长度,初始化值)赋值初始化:vector<数据类型>变量名={1,2,3,4,5}可以作为数组数组开头:array.begin()数组结尾:array.end()数组大小:array.size()添加元素到......
  • 使用c#实现23种常见的设计模式
    使用c#实现23种常见的设计模式设计模式通常分为三个主要类别:创建型模式结构型模式行为型模式。这些模式是用于解决常见的对象导向设计问题的最佳实践。以下是23种常见的设计模式并且提供c#代码案例:创建型模式:1.单例模式(Singleton)publicsealedclassSingleton......
  • c++中正确使用round()来四舍五入计算
    说明四舍五入的函数参数可以有多种数据类型。不同的数据类型有不同的结果。当他的参数应该是浮点数的时候,结果才是真正的四舍五入。例子/*g++-g-std=c++17./src/basic_demo.cpp-obasic_demo*/#include<iostream>#include<cmath>voidtest_round(){//参数是......
  • C++ 随机数
    ​在许多情况下,需要生成随机数。关于随机数生成器,有两个相关的函数。一个是 rand(),该函数只返回一个伪随机数。生成随机数之前必须先调用 srand() 函数。 下面是一个关于生成随机数的简单实例。实例中使用了 time() 函数来获取系统时间的秒数,通过调用rand()函数来生......
  • C++ 定义数字
     我们已经在之前章节的各种实例中定义过数字。下面是一个C++中定义各种类型数字的综合实例:实例#include<iostream>usingnamespacestd; intmain(){//数字定义shorts;inti;longl;floatf;doubled; //数字赋值s=10;i=1000;l=1000000;f=23......
  • visual studio 2010 c++ 创建com组件
    在VisualStudio2010中创建COM组件需要执行以下步骤:1. 打开VisualStudio2010,选择“新建项目”。2. 在弹出的对话框中选择“VisualC++”-->“Win32”-->“Win32项目”,并选择“DLL”作为应用程序类型。3. 单击“下一步”按钮。在下一个页面上,选择“ATL”,然后单击“完......