c++单例模式的一种写法

首言

在以前的文章中,我写了一种单例模式。不过那种写法会比较麻烦,要加好几行代码。如今看到了大佬写的新的单例模式,我进行了改进,比较好玩,现在记录下来。

大佬的单例模式

#include <stdexcept>

template <typename T>
class Singleton {
public:
    template<typename... Args>
    static T* Instance( Args&&... args ) {
        if ( m_pInstance == nullptr )
            m_pInstance = new T( std::forward<Args>( args )... );

        return m_pInstance;

    }

    static T* GetInstance( ) {
        if ( m_pInstance == nullptr )
            throw std::logic_error( "the instance is not init, please initialize the instance first" );

        return m_pInstance;
    }

    static void DestroyInstance( ) {
        delete m_pInstance;
        m_pInstance = nullptr;
    }

private:
    static T* m_pInstance;
};

template <class T> T*  Singleton<T>::m_pInstance = nullptr;
#include "Singleton.h"

class Test: public Singleton<Test>
{
public:
    Test(int selfNum):_selfNum(selfNum) {};
    void sayhello(){
    	std::cout<<"hello--"<<_selfNum<<std::endl;
	};
protected:
    int _selfNum = -1;
};

使用时是这样的

	Test one(1);
    Test two(2);
    one.sayhello();
    two.sayhello();
    Singleton<Test>::Instance(3);
    Singleton<Test>::GetInstance()->sayhello();
    Test::Instance(4);
    Test::GetInstance()->sayhello();

打印结果

hello--1
hello--2
hello--3
hello--3

为什么最后两条是一样的数字呢?因为 Test 继承了 Singleton<Test> ,所以最后两种写法是等价的。

这里有一个大问题,假如别人使用这个类,同时忘记需要写成单例模式,就像 Test one(1);一样,那么代码就乱套了,针对这个问题,进行下列改动。

改进后代码

#include "Singleton.h"

class Test: public Singleton<Test>
{
public:
    friend class Singleton;
    
    void sayhello(){
    	std::cout<<"hello--"<<_selfNum<<std::endl;
	};
protected:
    Test(int selfNum):_selfNum(selfNum) {};
    int _selfNum = -1;
};

使用了 friend 关键字,让 Singleton 可以访问 Test 的被保护函数,同时将 Test 的构造函数放入保护段,这样封住了可能出问题的部分。

相关推荐

  1. 模式C++写法

    2024-07-09 17:52:01       54 阅读
  2. c++模式写法

    2024-07-09 17:52:01       26 阅读
  3. 模式写法

    2024-07-09 17:52:01       62 阅读
  4. 模式具体写法

    2024-07-09 17:52:01       55 阅读
  5. 模式多种写法

    2024-07-09 17:52:01       32 阅读
  6. C++模式(三方式)

    2024-07-09 17:52:01       32 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-09 17:52:01       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-09 17:52:01       72 阅读
  3. 在Django里面运行非项目文件

    2024-07-09 17:52:01       58 阅读
  4. Python语言-面向对象

    2024-07-09 17:52:01       69 阅读

热门阅读

  1. nunjucks动态更新模版路径

    2024-07-09 17:52:01       24 阅读
  2. 【python技巧】pytorch网络可视化

    2024-07-09 17:52:01       28 阅读
  3. 单例模式的实现

    2024-07-09 17:52:01       22 阅读
  4. 【MIT 6.5840/6.824】Lab1 MapReduce

    2024-07-09 17:52:01       21 阅读
  5. 【云原生】Kubernetes之持久化

    2024-07-09 17:52:01       22 阅读
  6. urlib Python爬虫

    2024-07-09 17:52:01       29 阅读
  7. 【MySQL】SQL中的DROP、DELETE和TRUNCATE的区别

    2024-07-09 17:52:01       37 阅读
  8. 云原生监控-Kubernetes-Promethues-Grafana

    2024-07-09 17:52:01       30 阅读
  9. arm (exti中断)

    2024-07-09 17:52:01       29 阅读