VSCode上通过C++实现单例模式

单例模式实际上就是为了确保一个类最多只有一个实例,并且在程序的任何地方都可以访问这个实例,也就是提供一个全局访问点,单例对象不需要手动释放,交给系统来释放就可以了,单例模式的设计初衷就是为了在整个应用程序的生命周期中只创建一个实例,并且在需要时重复使用该实例,而不是频繁地创建和销毁对象。因此,在应用程序运行期间,单例对象通常会一直存在,直到应用程序结束。

一般来说,实现单例模式的方式有两种,一种是懒加载的方式,另外一种是预加载的方式。

实际上实现单例模式的基本步骤其实是一样的。第一步都是将构造函数和析构函数私有化,然后定义一个静态单例对象和声明一个静态单例对象获取函数,最后初始化单例对象和定义单例对象获取函数。

懒加载:当使用到单例对象的时候,才创建这个对象。

main函数

cpp 复制代码
#include"Test.h"
#include<iostream>
int main()
{
    Test*t1=Test::get_instance();
    Test*t2=Test::get_instance();
    std::cout<<"t1:"<<t1<<std::endl;
    std::cout<<"t2:"<<t2<<std::endl;
    return 0;
}

Test.h

将构造函数私有化 ,可以阻止外部代码直接实例化类的对象,强制使用单例模式提供的静态方法来获取类的唯一实例。这样可以确保在整个应用程序中只有一个实例存在。通过私有化析构函数,可以防止外部代码直接删除单例对象,从而确保单例对象在整个应用程序的生命周期内保持存在。这有助于避免意外的对象销毁和内存泄漏。

将单例对象(t_instance)声明为静态的是为了确保单例对象的唯一性、全局访问性和简化访问方式。静态单例对象可以在整个应用程序中被直接访问,避免多次实例化的情况发生,符合单例模式的设计原则

cpp 复制代码
class Test
{
public:
static Test*get_instance();
private:
Test();
~Test();
static Test*t_instance;
};

Test.cpp

cpp 复制代码
#include"Test.h"
Test*Test::t_instance=nullptr;
Test *Test::get_instance()
{
    if(t_instance==nullptr)
    {
        t_instance=new Test();
    }
    return t_instance;
}
Test::Test()
{

}
Test::~Test()
{
delete t_instance;
}

运行代码,可以发现,两个Test对象的地址是一样的,也就是说明这两个对象是同一个对象。

上面这种写法的懒加载其实是线程不安全的,当多个线程调用get_instance函数时,可能会创建出多个对象,将单例获取函数改进一下就可以了。

cpp 复制代码
#include<mingw.mutex.h>
class Test
{
public:
static Test*get_instance();
private:
Test();
~Test();
static Test*t_instance;
static std::mutex tmutex;
};
cpp 复制代码
#include"Test.h"
Test*Test::t_instance=nullptr;
std::mutex Test::tmutex;
Test *Test::get_instance()
{
    if(t_instance==nullptr)
    {
        std::lock_guard<std::mutex>lk(tmutex);
        t_instance=new Test();
    }
    return t_instance;
}
Test::Test()
{

}
Test::~Test()
{
delete t_instance;
}

预加载:程序启动的时候,就将对象创建好。

只需要更改懒加载的Test.cpp就可以了,不必判断单例对象是否为空,在类被第一次使用的时候就直接创建好了单例对象。

cpp 复制代码
#include"Test.h"
Test*Test::t_instance=new Test();
Test *Test::get_instance()
{
    return t_instance;
}
Test::Test()
{

}
Test::~Test()
{
delete t_instance;
}
相关推荐
hdsoft_huge1 小时前
Java & Spring Boot常见异常全解析:原因、危害、处理与防范
java·开发语言·spring boot
研华嵌入式1 小时前
如何在高通跃龙QCS6490 Arm架构上使用Windows 11 IoT企业版?
arm开发·windows·嵌入式硬件
风中的微尘1 小时前
39.网络流入门
开发语言·网络·c++·算法
未来之窗软件服务2 小时前
幽冥大陆(二)RDIFSDK 接口文档:布草洗涤厂高效运营的技术桥梁C#—东方仙盟
开发语言·c#·rdif·仙盟创梦ide·东方仙盟
混分巨兽龙某某2 小时前
基于Qt Creator的Serial Port串口调试助手项目(代码开源)
c++·qt creator·串口助手·serial port
小冯记录编程2 小时前
C++指针陷阱:高效背后的致命危险
开发语言·c++·visual studio
1uther3 小时前
Unity核心概念⑨:Screen
开发语言·游戏·unity·c#·游戏引擎
C_Liu_3 小时前
C++:类和对象(下)
开发语言·c++
coderxiaohan3 小时前
【C++】类和对象1
java·开发语言·c++
阿昭L3 小时前
MFC仿真
c++·mfc