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;
}
相关推荐
C++ 老炮儿的技术栈19 分钟前
UDP 与 TCP 的区别是什么?
开发语言·c++·windows·算法·visual studio
wgslucky24 分钟前
Dubbo报错:module java.base does not “opens java.lang“ to unnamed module
java·开发语言·dubbo
whyeekkk1 小时前
python打卡第48天
开发语言·python
DougLiang2 小时前
关于easyexcel动态下拉选问题处理
java·开发语言
mochensage2 小时前
CSP信奥赛C++常用系统函数汇总
c++·信奥
mochensage2 小时前
C++信息学竞赛中常用函数的一般用法
java·c++·算法
fpcc2 小时前
跟我学c++中级篇——多线程中的文件处理
c++
全职计算机毕业设计3 小时前
基于Java Web的校园失物招领平台设计与实现
java·开发语言·前端
5:003 小时前
云备份项目
linux·开发语言·c++
笨笨马甲3 小时前
Qt Quick模块功能及架构
开发语言·qt