【C++】单例模式
创始人
2024-03-21 02:21:55

目录

1.如何提供一个全局变量来记录函数调用次数呢?

        2.1饿汉模式

        2.2懒汉模式

                2.2.1实现一个内嵌垃圾回收类 

懒汉的另一种写法


1.如何提供一个全局变量来记录函数调用次数呢?

声明定义分离

func.h 

extern int Count ;//声明

func.cpp

#include "func.h"int Count = 0;//定义void func()
{for (int i = 10; i > 0; i--){++Count;}
}

test.cpp

#include "func.h"int main()
{func();cout << "count:" << Count << endl;return 0;
}

 

2.单例模式

定义:一个类只能创建一个对象,即单例模式,该模式可以保证系统中该类只有一个实例,并提供一个访问它的全局访问(GetInstance)该实例被所有程序模块共享(所以文件都可以访问)。

2.1饿汉模式

饿汉模式:饿了随时准备吃,在调用之前就定义好了

singleton.h 

  • 单例模式只有一个对象:那么构造函数私有且声明一个静态对象(类::静态对象函数可以访问),再除了singleton.h的任意一个文件定义,再使用一个静态成员去取那个唯一的对象就达到需求;
  • 单例不可以拷贝,所有拷贝构造防拷贝;赋值重载不需要,因为赋值重载需要两个定义的对象
//饿汉模式
class GetInformation
{
public:static GetInformation& GetInstance(){return instance;}void Add(const int n)//对象私有+需要一个接口函数{_count += n;}int GetConut()//个数{return _count;}GetInformation(const GetInformation& instance)=delete;//单例不能拷贝,防拷贝
private:GetInformation(int n=0):_count(n){}int _count;static GetInformation instance;//类里面都是声明
};

singleton.cpp 

#include "singleton.h"
GetInformation GetInformation::instance(0);//定义,静态成员可以用类名+::访问void func()
{for (int i = 10; i > 0; i--){GetInformation::GetInstance().Add(1);}
}

test.cpp

#include "singleton.h"
int main()
{func();cout << "GetCount:" << GetInformation::GetInstance().GetConut() << endl;return 0;
}

执行结果

 

 2.2懒汉模式

懒汉模式:在第一次调用时才定义

singleton.h 

  • 单例模式只有一个对象:那么构造函数私有且声明一个静态对象指针(类::静态对象函数可以访问),再除了singleton.h的任意一个文件定义为nullptr,在第一次调用是new一个对象;再使用一个静态成员去取那个唯一的对象就达到需求
  • 单例不可以拷贝,所有拷贝构造防拷贝;赋值重载不需要,因为赋值重载需要两个定义的对象
//懒汉模式
class GetInformation
{
public:static GetInformation& GetInstance(){if (instance == nullptr)//第一次调用new一个对象处理{instance = new GetInformation;}return *instance;}void Add(const int n){instance->_count += n;}int GetConut(){return instance->_count;}GetInformation(const GetInformation& instance) = delete;//防拷贝GetInformation(int n = 0):_count(n){}private:int _count;static GetInformation* instance;类里面都是声明
};

singleton.cpp 

#include "singleton.h"GetInformation* GetInformation::instance=nullptr;//定义,静态成员可以用类名+::访问void func()
{for (int i = 10; i > 0; i--){GetInformation::GetInstance().Add(1);}
}

test.cpp

#include "singleton.h"int main()
{func();cout << "Getount:" << GetInformation::GetInstance().GetConut() << endl;return 0;
}

执行结果

2.2.1实现一个内嵌垃圾回收类 

  • 在懒汉模式中声明周期结束,只有一个对象指针,new出来的空间没有得到释放
  •  一般懒汉的单例对象,不需要回收,因为进程正常结束,资源都会还给系统,这个对象只有一个系统自动回收也没什么问题, 但是如果在单例对象释放析构时,有一些要完成的动作,比如要记录日志等等。那么可以考虑搞一个类似下面的回收类帮助去完成这个事情.

singleton.h 

  • 生命周期结束,内嵌垃圾回收类对象自动析构
//懒汉模式
class GetInformation
{
public:static GetInformation& GetInstance(){if (instance == nullptr){instance = new GetInformation;}return *instance;} GetInformation(const GetInformation& instance) = delete;GetInformation(int n = 0):_count(n){}// 实现一个内嵌垃圾回收类 class CGarbo{~CGarbo(){if (instance != nullptr){delete instance;}}private:};
private:static CGarbo _CGarbo;int _count;static GetInformation* instance;//声明
};

singleton.cpp

#include "singleton.h"GetInformation* GetInformation::instance=nullptr;//定义,静态成员可以用类名+::访问
GetInformation::CGarbo _CGarbo;//垃圾回收定义

懒汉模式和饿汉模式的优缺点

 

懒汉的另一种写法

  • 在C++11更推荐这种懒汉写法,它解决了懒汉的缺点
//饿汉模式
class GetInformation
{
public:static GetInformation& GetInstance(){// C++98 中多线程调用时,static sInst对象构造初始化并不能保证下线程安全// C++11 优化了这个问题,C++11中static sInst对象构造初始化是线程安全的static GetInformation instance;return instance;}void Add(const int n){_count += n;}int GetConut(){return _count;}GetInformation(const GetInformation& instance)=delete;
private:GetInformation(int n=0):_count(n){}int _count;
};

相关内容

热门资讯

美伊、美俄乌,将同日同城谈判! 据路透社13日报道,新一轮美伊谈判和美俄乌会谈将于17日在瑞士日内瓦举行。路透社援引消息人士的话说,...
跳冰河救人骑手获见义勇为奖金 【#跳冰河救人骑手获见义勇为奖金#】2月12日下午,美团骑手张蒙蒙在送单过程中路过冰窖口胡同西口转河...
欢乐过大年·乡“亲”京郊行 |... 京郊过大年冰雪嬉乐、鲜果采摘、传统年俗、非遗体验、地道美食一站式集齐,承包你的新春欢乐!这份诚意满满...
2026黄精十大口碑品牌汇总,... 现代生活节奏不断加快,许多人频繁感受到精神倦怠、气血亏虚、晨起乏力等健康困扰,尤其在高强度工作压力与...
AI年代,哲学在场?——商务印... 近日,由商务印书馆出版的轻学术丛书“在场”与读者见面。该书首辑由三位女性哲学学者撰写,分别是《拟像-...