• 【C++】单例模式


    目录

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

            2.1饿汉模式

            2.2懒汉模式

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

    懒汉的另一种写法


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

    声明定义分离

    func.h 

    extern int Count ;//声明

    func.cpp

    1. #include "func.h"
    2. int Count = 0;//定义
    3. void func()
    4. {
    5. for (int i = 10; i > 0; i--)
    6. {
    7. ++Count;
    8. }
    9. }

    test.cpp

    1. #include "func.h"
    2. int main()
    3. {
    4. func();
    5. cout << "count:" << Count << endl;
    6. return 0;
    7. }

     

    2.单例模式

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

    2.1饿汉模式

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

    singleton.h 

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

    singleton.cpp 

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

    test.cpp

    1. #include "singleton.h"
    2. int main()
    3. {
    4. func();
    5. cout << "GetCount:" << GetInformation::GetInstance().GetConut() << endl;
    6. return 0;
    7. }

    执行结果

     

     2.2懒汉模式

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

    singleton.h 

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

    singleton.cpp 

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

    test.cpp

    1. #include "singleton.h"
    2. int main()
    3. {
    4. func();
    5. cout << "Getount:" << GetInformation::GetInstance().GetConut() << endl;
    6. return 0;
    7. }

    执行结果

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

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

    singleton.h 

    • 生命周期结束,内嵌垃圾回收类对象自动析构
    1. //懒汉模式
    2. class GetInformation
    3. {
    4. public:
    5. static GetInformation& GetInstance()
    6. {
    7. if (instance == nullptr)
    8. {
    9. instance = new GetInformation;
    10. }
    11. return *instance;
    12. }
    13. GetInformation(const GetInformation& instance) = delete;
    14. GetInformation(int n = 0)
    15. :_count(n)
    16. {}
    17. // 实现一个内嵌垃圾回收类
    18. class CGarbo
    19. {
    20. ~CGarbo()
    21. {
    22. if (instance != nullptr)
    23. {
    24. delete instance;
    25. }
    26. }
    27. private:
    28. };
    29. private:
    30. static CGarbo _CGarbo;
    31. int _count;
    32. static GetInformation* instance;//声明
    33. };

    singleton.cpp

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

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

     

    懒汉的另一种写法

    • 在C++11更推荐这种懒汉写法,它解决了懒汉的缺点
    1. //饿汉模式
    2. class GetInformation
    3. {
    4. public:
    5. static GetInformation& GetInstance()
    6. {
    7. // C++98 中多线程调用时,static sInst对象构造初始化并不能保证下线程安全
    8. // C++11 优化了这个问题,C++11中static sInst对象构造初始化是线程安全的
    9. static GetInformation instance;
    10. return instance;
    11. }
    12. void Add(const int n)
    13. {
    14. _count += n;
    15. }
    16. int GetConut()
    17. {
    18. return _count;
    19. }
    20. GetInformation(const GetInformation& instance)=delete;
    21. private:
    22. GetInformation(int n=0)
    23. :_count(n)
    24. {}
    25. int _count;
    26. };
  • 相关阅读:
    vue3模板-vscode设置(语法糖)
    7-25 念数字
    ARMv7-A 那些事 - 7.栈回溯浅析
    c++学习 之 强制类型转换
    [极客大挑战 2019]EasySQL
    HDFS文件读取流程
    解决cloudflare pages部署静态页面发生404错误的问题
    京东发布第三季度财报员工总数近50万 “以实助实”助力高质量就业
    机器学习——梯度下降算法
    SplitMask:大规模数据集是自我监督预训练的必要条件吗?
  • 原文地址:https://blog.csdn.net/m0_72964546/article/details/128174846